Drawing between two images in 1 JPanel

I want to draw lines between 2 JScrollPanes (the first scroll bar on the left side, the second on the right). These JScrollPanes contain images. I want to draw lines between these two images (use several layers, use some tricks, etc.). I tried to do it differently, but I failed. Is it possible? (if not, I will have to make 2 images in one JScrollPane , and it will not be very nice).

EDIT

I want to draw between 2 images - through the components - to get some dots from the images and draw lines between them. I apologize for the poorly worded question.

+3
source share
3 answers

To do this, I believe you need to use Glass Pane . Glass Pane sits on top of everything in JRootPane and fills the entire view. This particular position allows you to use two different possibilities:

  • Interception of mouse and keyboard events
  • Drawing the entire user interface

I believe that your question is being solved by the second opportunity. The following is an example implementation that you can later adapt to meet your own needs. Please note that I did not focus on Glass Pane , which you will need to explore on your own.

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(); } } } } 

OUTPUT

enter image description here

EXPLANATION

In this example, I clicked two arbitrary points in each JLabel and then drew a connecting line.

+7
source

It should be very possible. You will need to create a custom component that will know about vertical ScrollBars. He must add himself as an AdjustmentListener to each scroll bar to detect changes and redraw the lines between them.

See: addAdjustmentListener method in API

+2
source

You can use this http://java-sl.com/connector.html as an example of such code.

+2
source

Source: https://habr.com/ru/post/897007/


All Articles