2010-10-17 2 views
4

Я пытался найти способ (в Swing) для подключения двух JInternalFrame s с CubicCurve2D (иначе известный как кривая безьего кубика). Общий эффект, который я пытаюсь достичь, - это интерфейс, похожий на Yahoo! Pipes (кривая должна идти от нижней части одного внутреннего кадра до другого).CubicCurve2D, соединяющий два экземпляра JInternalFrame

Кто-нибудь здесь сделал это раньше? Проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как рисовать кривую обновления способом, который видим пользователю. Рисование, а затем перекраска JDesktopPane.getGraphics, похоже, ничего не делает.

Если возможно, я хотел бы использовать буфер вне экрана.

ответ

10

Да. Вот пример с использованием drawLine(int x1, int y1, int x2, int y2), но вызов draw(Shape s) на вашей кривой - это простое расширение. Возможно, вам придется развернуть ComponentAdapter, чтобы обрабатывать события изменения размера.

alt text

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Stroke; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import javax.swing.JDesktopPane; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 

/** @see http://stackoverflow.com/questions/3951383 */ 
public class JDPTest extends JDesktopPane { 

    private static final Stroke s = new BasicStroke(4.0f); 
    private MyFrame one = new MyFrame("One", 100, 100); 
    private MyFrame two = new MyFrame("Two", 400, 240); 

    public JDPTest() { 
     this.setPreferredSize(new Dimension(640, 480)); 
     this.add(one); 
     this.add(two); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setColor(Color.lightGray); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 
     g2d.setColor(Color.blue); 
     g2d.setStroke(s); 
     int x1 = one.getX() + one.getWidth()/2; 
     int y1 = one.getY() + one.getHeight()/2; 
     int x2 = two.getX() + two.getWidth()/2; 
     int y2 = two.getY() + two.getHeight()/2; 
     g2d.drawLine(x1, y1, x2, y2); 
    } 

    private final class MyFrame extends JInternalFrame { 

     MyFrame(String name, int x, int y) { 
      super(name); 
      this.setSize(160, 100); 
      this.setLocation(x, y); 
      this.setVisible(true); 
      this.addComponentListener(new ComponentAdapter() { 

       @Override 
       public void componentMoved(ComponentEvent e) { 
        JDPTest.this.repaint(); 
       } 
      }); 
     } 
    } 

    private void display() { 
     JFrame f = new JFrame("JDPTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new JDPTest().display(); 
      } 
     }); 
    } 
} 
+0

У меня нет времени, чтобы попробовать это прямо сейчас, но спасибо за скриншот! Я возьму это как доказательство, чтобы принять это как правильный ответ. – KPthunder

+0

Теперь, когда я смотрю на картинку, я вижу, что забыл подсказки рендеринга! При поверхностном тестировании он обновляется при перетаскивании других L & F. К сожалению, CDE/Motif обновляется только с помощью мыши. – trashgod

+0

+1, просто увидел этот пример в первый раз. – camickr

3

Попробуйте это. Я только что изменил приведенный выше код.

enter image description here

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Stroke; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.awt.geom.CubicCurve2D; 

import javax.swing.JDesktopPane; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 

/** @see http://stackoverflow.com/questions/3951383 */ 
public class JDPTest extends JDesktopPane { 

    private static final Stroke s = new BasicStroke(4.0f); 
    private MyFrame one = new MyFrame("One", 100, 100); 
    private MyFrame two = new MyFrame("Two", 400, 240); 
    CubicCurve2D cubcurve; 
    public JDPTest() { 
     this.setPreferredSize(new Dimension(640, 480)); 
     this.add(one); 
     this.add(two); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setColor(Color.lightGray); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 
     g2d.setColor(Color.blue); 
     g2d.setStroke(s); 
     int x1 = one.getX() + one.getWidth()/2; 
     int y1 = one.getY() + one.getHeight()/2; 
     int x2 = two.getX() + two.getWidth()/2; 
     int y2 = two.getY() + two.getHeight()/2; 

     cubcurve = new CubicCurve2D.Float(x1,y1,x1+200,y1-115,x2-200,y2+115,x2,y2); 
     g2d.draw(cubcurve); 

     // g2d.drawLine(x1, y1, x2, y2); 
    } 

    private final class MyFrame extends JInternalFrame { 

     MyFrame(String name, int x, int y) { 
      super(name); 
      this.setSize(160, 100); 
      this.setLocation(x, y); 
      this.setVisible(true); 
      this.addComponentListener(new ComponentAdapter() { 

       @Override 
       public void componentMoved(ComponentEvent e) { 
        JDPTest.this.repaint(); 
       } 
      }); 
     } 
    } 

    private void display() { 
     JFrame f = new JFrame("JDPTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 


      public void run() { 
       new JDPTest().display(); 
      } 
     }); 
    } 
}