I have a task to make an application which will do the following:
So the problem is that when I do mouse click - it's fine, button moves to coordinates of click, but when I start moving mouse the button comes back to the original position.
public class Window extends JFrame {
private JLabel statusBar;
private JPanel mainPanel, statusBarPanel;
JButton button;
public Window()
{
super("Window");
setSize(400,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel=new JPanel();
statusBarPanel = new JPanel();
statusBar=new JLabel("Coords: ");
add(statusBarPanel, BorderLayout.SOUTH);
add(mainPanel,BorderLayout.CENTER);
mainPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
statusBarPanel.add(statusBar,BorderLayout.CENTER);
button = new JButton("Default text");
mainPanel.add(button);
MyMouseListener myMouseListener=new MyMouseListener();
mainPanel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
statusBar.setText("Coords: ("+e.getX()+":"+e.getY()+")");
}
});
mainPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
button.setLocation(e.getX()-button.getWidth()/2,e.getY()-button.getHeight()/2);
}
});
mainPanel.setFocusable(true);
setVisible(true);
}
}
This is one of the rare cases where you don't want your panel to have a layout manager, since you need absolute positioning.
JPanel
has a default layout manager which is a FlowLayout
, and your call to setLocation
will only have a temporary effect until the panel revalidates its content and places things where they were supposed to be initially.
See the following example with comments, it should give you the general idea :
public class Window extends JFrame {
private final JLabel statusBar;
private final JPanel mainPanel, statusBarPanel;
JButton button;
public Window() {
super("Window");
setSize(400, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel = new JPanel();
mainPanel.setLayout(null);// no layout for absolute positioning
statusBarPanel = new JPanel();
statusBar = new JLabel("Coords: ");
add(statusBarPanel, BorderLayout.SOUTH);
add(mainPanel, BorderLayout.CENTER);
mainPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
statusBarPanel.add(statusBar, BorderLayout.CENTER);
button = new JButton("Default text");
// place the button "manually"
button.setBounds((int) (400 - button.getPreferredSize().getWidth()) / 2, 0,
(int) button.getPreferredSize().getWidth(),
(int) button.getPreferredSize().getHeight());
mainPanel.add(button);
mainPanel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(final MouseEvent e) {
super.mouseMoved(e);
statusBar.setText("Coords: (" + e.getX() + ":" + e.getY() + ")");
}
});
mainPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
super.mouseClicked(e);
button.setLocation((int) (e.getX() - button.getPreferredSize().getWidth() / 2),
(int) (e.getY() - button.getPreferredSize().getHeight() / 2));
}
});
mainPanel.setFocusable(true);
setVisible(true);
}
}