我想绘制2 JScrollPanes
之间的线条(左侧第一个滚动窗格,右侧第二个)。这些JScrollPanes
包含图片。我想在这两个图像之间画线(使用一些图层,使用一些技巧等)。我尝试了不同的方式,但我失败了。可能吗? (如果没有,我将不得不在一个JScrollPane
制作2张图片,这样就不太好了。
修改
我想绘制两幅图像 - 通过组件 - 从图像中获取一些点并在它们之间绘制线条。我为制定不好的问题道歉。
答案 0 :(得分:7)
为了实现这一目标,我相信您需要使用Glass Pane
。 Glass Pane
位于JRootPane
中的所有内容之上,并填充整个视图。这个特殊的位置允许两个不同的功能:
我相信你的问题是由第二种能力解决的。以下是一个示例实现,您可以稍后根据自己的需要进行定制。请注意,我已经遗漏了很多关于您需要自己研究的Glass Pane
的详细信息。
<强> CODE 强>
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GlassPaneDemo {
private static BufferedImage bi;
public static void main(String[] args){
try {
loadImages();
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
createAndShowGUI();
}
});
} catch (IOException e) {
// handle exception
}
}
private static void loadImages() throws IOException{
bi = ImageIO.read(new File("src/resources/person.png"));
}
private static void createAndShowGUI(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setGlassPane(new CustomGlassPane());
frame.getContentPane().add(getButtonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.getGlassPane().setVisible(true);
frame.setVisible(true);
}
private static final JPanel getButtonPanel(){
@SuppressWarnings("serial")
final JPanel panel = new JPanel(){
@Override
protected void paintComponent(Graphics g){
Graphics gCopy = g.create();
gCopy.setColor(Color.BLUE.darker());
gCopy.fillRect(0, 0, getWidth(), getHeight());
gCopy.dispose();
}
};
final JLabel labelOne = new JLabel();
labelOne.setIcon(new ImageIcon(bi));
final JLabel labelTwo = new JLabel();
labelTwo.setIcon(new ImageIcon(bi));
panel.add(labelOne);
panel.add(labelTwo);
return panel;
}
@SuppressWarnings("serial")
private static class CustomGlassPane extends JComponent{
private Point p1;
private Point p2;
private boolean lineDrawn;
public CustomGlassPane(){
addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e){
if(p1 == null || lineDrawn){
if(lineDrawn){
p1 = null;
p2 = null;
lineDrawn = false;
}
p1 = e.getPoint();
}else{
p2 = e.getPoint();
repaint(); // not optimal
lineDrawn = true;
}
}
});
// Block all other input events
addMouseMotionListener(new MouseMotionAdapter(){});
addKeyListener(new KeyAdapter(){});
addComponentListener(new ComponentAdapter(){
@Override
public void componentShown(ComponentEvent e){
requestFocusInWindow();
}
});
setFocusTraversalKeysEnabled(false);
}
@Override
protected void paintComponent(Graphics g){
if(p1 != null && p2 != null){
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.RED);
g2.drawLine((int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY());
g2.dispose();
}
}
}
}
<强>输出强>
<强>说明强>
在这个例子中,我点击了每个JLabel
中的两个任意点,然后绘制了一条连接线。
答案 1 :(得分:2)
这应该是非常可能的。您需要创建一个知道两个垂直ScrollBars的自定义组件。它应该将自己添加为每个滚动条的AdjustmentListener
,以便检测更改并重新绘制两者之间的线条。
答案 2 :(得分:2)
你可以用它 http://java-sl.com/connector.html 作为此类代码的一个例子。