1

I have a JFrame in which there is a JToolBar and a JPanel. I have to draw lines interactively in the panel by capturing mouse clicks with MouseListener. The mouse clicks are captured and the paintComponent method is even executed (I tested these using dialog boxes) but nothing is drawn in the panel. I think there is a problem with repaint() (called in mousePressed()) or the method paintComponent() but I don't know what it is. What is wrong with the code?

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;

public class Clipping extends JPanel implements MouseListener, ActionListener
{
    static JFrame frame;
    static JComboBox cboDraw;
    static JButton btnClear;
    static JButton btnClip;

    double x1, y1, x2, y2;
    boolean FirstPoint;

    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                CreateFrame();
            }
        });
    }

    private static void CreateFrame()
    {
        frame = new JFrame("Clipping");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Clipping());
        frame.setSize(500,500);
        frame.setVisible(true);
    }

    public Clipping()
    {
        setLayout(new BorderLayout());

        JToolBar toolbar = new JToolBar(JToolBar.VERTICAL);
        PopulateToolBar(toolbar);
        add(toolbar, BorderLayout.WEST);

        addMouseListener(this);
        cboDraw.addMouseListener(this);
        btnClip.addActionListener(this);
        btnClear.addActionListener(this);

    }

    private static void PopulateToolBar(JToolBar toolbar)
    {
        String[] cboList = {"Line", "Polygon"};
        cboDraw = new JComboBox(cboList);
        cboDraw.setMaximumSize(new Dimension(70,30));
        btnClip = new JButton("Set clip area");
        btnClear = new JButton("Clear");

        toolbar.add(cboDraw);
        toolbar.addSeparator();
        toolbar.add(btnClip);
        toolbar.addSeparator();
        toolbar.add(btnClear);

        cboDraw.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnClip.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnClear.setAlignmentX(Component.CENTER_ALIGNMENT);

        toolbar.setMargin(new Insets(10,10,10,10));
        toolbar.setFloatable(false);
        toolbar.setBackground(Color.black);
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        if (cboDraw.getSelectedIndex() == 0) //draw line
        {
            g2.draw(new Line2D.Double(x1, y1, x2, y2));
        }
    }

    public void mousePressed(MouseEvent e)
    {
        if (e.getSource() != cboDraw) //to prevent line coordinates from being saved when selecting from combobox
        {
            if (cboDraw.getSelectedIndex() == 0) //user wants to draw line
            {
                if (FirstPoint == false) //first coordinates
                {
                    x1 = e.getX();
                    y1 = e.getY();
                    FirstPoint = true;
                }
                else //second coordinates
                {
                    x2 = e.getX();
                    y2 = e.getY();
                    repaint();
                    FirstPoint = false;
                }
            }
        }
    }

    public void actionPerformed(ActionEvent e) {}
    public void mouseClicked(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}
Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59
Saiyan
  • 197
  • 7
  • 22
  • 5
    You seem to define the drawing for `Clipping`, but then you add a `JPanel` to the center position of that - the panel would cover any custom drawing you have in `Clipping`. – kiheru Feb 17 '15 at 09:59
  • 3
    1) Please learn common Java nomenclature (naming conventions - e.g. `EachWordUpperCaseClass`, `firstWordLowerCaseMethod()`, `firstWordLowerCaseAttribute` unless it is a `UPPER_CASE_CONSTANT`) and use it consistently. 2) `static` is not our friend when it comes to GUI components, or most GUI related methods. Create an object of `Clipping` class and call it's non-static methods to create the GUI. – Andrew Thompson Feb 17 '15 at 10:08
  • @kiheru - Does this mean if I remove the JPanel and draw directly on the JFrame, it should work? I tried by commenting out, from Clipping(), the 3 lines of codes related to the panel and adding a mouse listener to the frame instead of the panel, but it does not work. – Saiyan Feb 17 '15 at 10:10
  • Just `addMouseListener(this)` would do the trick, **and** removing the check that the source is `panel` in `mousePressed()` (since it's the `Clipping` instance, not the `panel` which is now unused). You don't need to check the source, since you know where you attached the listener. Also, see how to [compare strings](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) in java for checking "Line", and how to [properly initialize](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html) a swing application. – kiheru Feb 17 '15 at 10:23
  • @kiheru - I put mouse listeners for specific controls because I need these for later. I also updated the code to properly initialise the application. The problem is not in any of this, though. The lines are still not drawn. What is wrong with the code? – Saiyan Feb 17 '15 at 10:40
  • You still have a panel covering the panel where you'd do the drawing, like I pointed out in the first comment... and also all the other issues mentioned in my second comment, with the exception of the thread use being fixed now (good!). Also, read Andrew's comment about good code practice. – kiheru Feb 17 '15 at 10:50
  • I removed all the codes related to the JPanel panel. Now it works. Thanks. – Saiyan Feb 17 '15 at 13:23
  • I updated the code. One thing I would like to confirm: the drawing is now done directly on the frame or on a panel (because of "extends JPanel")? – Saiyan Feb 17 '15 at 17:49
  • See also [this example](http://stackoverflow.com/questions/16244668/how-to-name-the-coordinates-points-in-java-swing/16246610#16246610) to perform a similar task. – Guillaume Polet Feb 17 '15 at 22:25

0 Answers0