staroselskii
staroselskii

Reputation: 365

Object sharing in Swing Framework

I've just started learning Java and have some noob questions. Below there is almost full listing of my program, because now I'd like to hear all the critics I can.

The "problem" I'm trying to solve is how to share an JLabel object between JPanels so that I can handle the events like MousePressed? I managed to handle a MousePressed event from PlotSurface: after I move somehow the cursor on the plane the JLabel coords get refreshed. But the code looks ugly to me. Any suggestions will be greatly appreciated!

The goal is to handle events from ControlsPanel (X,Y,Z and R can be changed). I'd like to draw a circle on the PlotSurface after these four are changed.

class PlotSurface extends JPanel {
    private ColoredCircle redCircle = new ColoredCircle();
    private Point start = new Point(0,0);
    private JLabel _label;
    public PlotSurface(JLabel label) 
    {
        _label = label;
        setBackground(Color.WHITE);
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                String pos = redCircle.getX() + "," + redCircle.getY();
                _label.setText(pos);
                moveCircle(e.getX(),e.getY());
            }
        });

        addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) {
               String pos = redCircle.getX() + "," + redCircle.getY();
                _label.setText(pos);
                moveCircle(e.getX(),e.getY());
            }
        });

    }

    private void moveCircle(int x, int y) {

        final int CURR_X = redCircle.getX();
        final int CURR_Y = redCircle.getY();
        final int CURR_W = redCircle.getWidth();
        final int CURR_H = redCircle.getHeight();
        final int OFFSET = 1;

        if ((CURR_X!=x) || (CURR_Y!=y)) {

        // The circle is moving, repaint background over the old square location. 
        repaint(CURR_X,CURR_Y,CURR_W+OFFSET,CURR_H+OFFSET);

        // Update coordinates.
        redCircle.setX(x);
        redCircle.setY(y);

        // Repaint the circle at the new location.
        repaint(redCircle.getX(), redCircle.getY(), 
        redCircle.getWidth()+OFFSET, 
        redCircle.getHeight()+OFFSET);
        }

    }

 @Override 
  public Dimension getPreferredSize() {
       return new Dimension(150,150);
   } 

 @Override 
  public void paintComponent(Graphics g) {
       super.paintComponent(g);       
       String pos = redCircle.getX() + "," + redCircle.getY();
       Graphics2D g2 = (Graphics2D) g;
       g2.drawString(pos,10,10); 
       g2.drawLine(0,getHeight()/2,getWidth(),getHeight()/2);
       g2.drawLine(getWidth()/2,0,getWidth()/2,getHeight());
       g2.fillOval(100,100,50,50);
       redCircle.paintCircle(g2);
  }     

}

class ColoredCircle{ //
 it know how to draw itself   }

class ControlsHeader extends JPanel 
{
    public ControlsHeader() {
        super();          
        JLabel lblR = new JLabel();
        lblR.setText("R: ");
        //...
        JSpinner x = new JSpinner(model);
        //...
        JComboBox y = new JComboBox();
        //..
        ButtonGroup z = new ButtonGroup();

         }
  }

class ControlsFooter extends JPanel 
{
    public ControlsFooter()
    {
        super();
        //a couple of elements
    }
}


class ControlsFrame extends JFrame 
{
    public ControlsFrame(String title) 
    {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(1000, 1000));

        JLabel coords = new JLabel();
        coords.setText("COORDS");
        coords.setForeground(Color.WHITE);
        JPanel footer = new ControlsFooter();
        footer.add(coords); 

        add(new PlotSurface(coords), BorderLayout.CENTER);        
        add(new ControlsHeader(), BorderLayout.NORTH);
        add(footer, BorderLayout.SOUTH);
    }
}
public class Lab4UI {

    private static void startGUI() {  
        JFrame frame = new ControlsFrame("Lab 4. №36");
        frame.pack();
        frame.setVisible(true);
    }

   public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {  
               startGUI(); 
        }});
}

}

Upvotes: 0

Views: 61

Answers (1)

Joop Eggen
Joop Eggen

Reputation: 109597

Labels are individuals, might have other texts, icons, positions, sizes. You could make your label class extending JLabel. But best seems to keep a separate class that may add/provide a MouseAdapter to/for a JLabel.

Sharing a JLabel is not feasible, as a realised component has a fixed parent container.

I cannot judge the overall context, but for myself I would first design an abstract system: plot surfaces, controlled by the mouse, maybe some common managing class sharing logic.

Maybe make two as independent as possible JPanel components, and then look what can be shared.


No need for coords to be given externally, as a JLabel cannot be shared.

public class PlotSurface extends JPanel {
    private ColoredCircle redCircle = new ColoredCircle();
    private Point start = new Point(0,0);
    private JLabel coords = new JLabel();
    private final MouseAdapter mouseAdapter = new MouseAdapter() {

        @Override
        public void mousePressed(MouseEvent e) {
            String pos = redCircle.getX() + "," + redCircle.getY();
            coords.setText(pos);
            moveCircle(e.getX(),e.getY()); // Or one param: e.getPoint().
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            String pos = redCircle.getX() + "," + redCircle.getY();
            coords.setText(pos);
            moveCircle(e.getX(),e.getY());
        }
    };

    public PlotSurface() 
    {
        coords.setText("COORDS");
        coords.setForeground(Color.WHITE);
        setBackground(Color.WHITE);
        addMouseListener(mouseAdapter);
        addMouseMotionListener(mouseAdapter);
    }

Upvotes: 1

Related Questions