MouseClick co-ordinates not working - java

I have a program which at the moment I am trying to find the position of co-ordinates on the panel when clicked. So far I'm currently get 0,0. Any suggestions?
P.S - Sorry about the lack of comments...
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.lang.Math;
public class ShapePanel extends JPanel{
private JButton startButton, stopButton;
private JTextField textField;
private JLabel label;
private Timer timer;
private final int DELAY = 5;
ArrayList<Shape> obj = new ArrayList<Shape>();
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ShapePanel());
frame.pack();
frame.setVisible(true);
}
public ShapePanel(){
DrawingPanel dpanel = new DrawingPanel();
JPanel cpanel = new JPanel();
startButton = new JButton("Start");
stopButton = new JButton("Stop");
cpanel.setLayout(new GridLayout(2,1));
cpanel.add(startButton);
cpanel.add(stopButton);
dpanel.addMouseListener(new MouseListen());
TimerListener tListen = new TimerListener();
startButton.addActionListener(tListen);
stopButton.addActionListener(tListen);
add(cpanel);
add(dpanel);
timer = new Timer(DELAY, tListen);
timer.start();
}
private class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e){
if (e.getSource() == timer){
for (int i = 0; i < obj.size(); i++){
obj.get(i).move();
}
}else if (e.getSource() == startButton){
timer.start();
}else if (e.getSource() == stopButton){
timer.stop();
}
repaint();
}
}
private class MouseListen implements MouseListener {
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
System.out.println(getX());
}
}
private class DrawingPanel extends JPanel{
DrawingPanel(){
setPreferredSize(new Dimension(400,400));
setBackground(Color.pink);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
for(int i = 0; i < obj.size(); i++){
obj.get(i).display(g);
}
}
}
}

Check the following portion of your code:
public void mouseClicked(MouseEvent e) {
System.out.println(getX());
// you are putting here only getX() which get the postion of panel
// put e.getX() instead
}

You need to implement the mouselistener correctly. The MouesEvent carries the position of the MouseClick.
public void mouseClicked(MouseEvent e) {
System.out.println(e.getPoint().x);
}

Related

Move JFrame from external jpanel class

I'm trying to move around jframe on the window through an event triggered from an external jpanel class, my code is below, but the doesn't achieve this. Instead the panel is the one that's moving around.
What am I doing wrong here? I am new programming in general.
package casuls_app;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Titlebar extends JPanel {
public Titlebar() {
btnClose =new JButton("X");
btnClose.setFocusable(false);
btnClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
closeButtonPressed(e);
}
}
);
controlBox =new JPanel(new GridLayout(1,1));
controlBox.setPreferredSize(new Dimension(150,40));
controlBox.add(btnClose);
controlBox.setBackground(new Color(255,255,255));
setLayout(new BorderLayout());
add(controlBox,BorderLayout.EAST);
setPreferredSize(new Dimension(0,40));
setBackground(new Color(60, 173, 205));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
mousePressedOnTitlebar(e);
}
}
);
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
mouseDraggedOnTitlebar(e);
}
}
);
}
private void mousePressedOnTitlebar(MouseEvent e) {
posX= e.getX();
posY=e.getY();
}
private void mouseDraggedOnTitlebar(MouseEvent e) {
setLocation(e.getXOnScreen() -posX, e.getYOnScreen() -posY);
}
private void closeButtonPressed(ActionEvent e){
System.exit(0);
}
//Variables declaration
private int posX,posY;
private JButton btnClose;
private JPanel controlBox;
}
setLocation() sets the location of your JPanel (because your class extends JPanel).
If you have a reference to the JFrame, you can call the setLocation method on that object.
frame.setLocation(x, y);
If you don't have the reference, then you can follow this post which accesses the frame via SwingUtilities:
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);

Wait for key before reading from a JTextField

I have a program that will make a JFrame with a JTextField. How do I get it to wait for text to be in the JTextField / the enter key is pressed?
public static void main(String[] args) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screenSize.getWidth();
int height = (int) screenSize.getHeight();
JFrame frame = new JFrame();
frame.getContentPane().add(new Text());
JTextField field = new JTextField(10);
frame.add(field, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width,height-55);
frame.setVisible(true);
// There is a keylistener here called listener. It was 100 lines. Did not want to copy
frame.addKeyListener(listener);
double x = 0;
x = Double.parseDouble(field.getText());
System.out.println(x);
I want
x = Double.parseDouble(field.getText());
to run only when someone types something in the JTextField in the JFrame.
Don't use a KeyListener
Add a DocumentListener to your JTextField's Document.
Inside of this listener check to see if the Document is empty or not.
If not empty, change the state of your program to allow the calculation, perhaps by enabling or disabling a JButton or Action.
For example:
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
public class DisbleButton extends JPanel {
private JTextField field = new JTextField(10);
private ButtonAction buttonAction = new ButtonAction();
private JButton button = new JButton(buttonAction);
public DisbleButton() {
add(field);
add(button);
buttonAction.setEnabled(false);
field.getDocument().addDocumentListener(new FieldDocListener());
}
private class FieldDocListener implements DocumentListener {
#Override
public void changedUpdate(DocumentEvent dEvt) {
testDoc(dEvt);
}
#Override
public void insertUpdate(DocumentEvent dEvt) {
testDoc(dEvt);
}
#Override
public void removeUpdate(DocumentEvent dEvt) {
testDoc(dEvt);
}
private void testDoc(DocumentEvent dEvt) {
Document doc = dEvt.getDocument();
buttonAction.setEnabled(doc.getLength() > 0);
}
}
private class ButtonAction extends AbstractAction {
public ButtonAction() {
super("Press Me");
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO do calculation here!
}
}
private static void createAndShowGui() {
DisbleButton mainPanel = new DisbleButton();
JFrame frame = new JFrame("DisbleButton");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

JButton setText() ERROR

I am trying to set a new text into a button when you press on it. However it does not seem to work, I am doing something wrong, and I do not know what...
EDIT -----I attach the code for easier comprehension of what I mean
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GrowAndShrinkSquareGUItest {
JFrame frame;
SquareDrawPanel bigGreen;
SquareDrawPanel smallGreen;
JButton button;
growAndShrinkListener listener;
public class SquareDrawPanel extends JPanel {
int width;
int height;
SquareDrawPanel(int w, int h) {
width = w;
height = h;
}
public void paintComponent(Graphics g) {
g.setColor(Color.green);
g.fillRect(frame.getWidth() / 2 - (width / 2), frame.getHeight()
/ 2 - (height / 2) - 15, width, height);
}
}
public class growAndShrinkListener implements ActionListener {
// JButton button;
growAndShrinkListener(JButton button) {
button = new JButton("Click me to grow the Square");
frame.add(button, BorderLayout.NORTH);
button.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
button.setText("Unselect all");
}
}
public static void main(String[] args) {
GrowAndShrinkSquareGUItest test = new GrowAndShrinkSquareGUItest();
test.go();
}
private void createPanels() {
bigGreen = new SquareDrawPanel(400, 400);
smallGreen = new SquareDrawPanel(100, 100);
}
private void drawPanel(JPanel panel) {
frame.add(panel);
panel.setVisible(true);
frame.add(panel, BorderLayout.CENTER);
}
private void createListenerButton() {
listener = new growAndShrinkListener(button);
}
private void loop(){}
public void go() {
frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createPanels();
drawPanel(smallGreen);
createListenerButton();
frame.setVisible(true);
}
}
It is because you use the button variable that is not defined in the scope of actionPerformed method. Java variables have scope and they are available inside curly braces where they're defined. The actionPerformed method is out of the curly braces of growAndShrinkListener method. The fixed code:
public class growAndShrinkListener implements ActionListener {
growAndShrinkListener(JButton button) {
button = new JButton("Click me to grow the Square");
frame.add(button, BorderLayout.NORTH);
button.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if(source instanceof JButton) {
button = (JButton) source;
button.setText("Click to shrink square");
}
}
}
Alternatively, you can use a private variable:
public class growAndShrinkListener implements ActionListener {
private JButton button;
growAndShrinkListener() {
button = new JButton("Click me to grow the Square");
frame.add(button, BorderLayout.NORTH);
button.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
button.setText("Click to shrink square");
}
}
Note: You should not overwrite the content of the argument in the constructor. The argument that you got is not a "pointer" to the callee's variable, but just a simple reference to that. If you overwrite, then the content will be lost for you and calle will not know that.
change like this..
public class YourSuperClass{
private JButton button;
public YourSuperClass(){
// your logics
button = new JButton();
button.addActionListener(new GrowAndShrinkListener(button));
frame.add(button, BorderLayout.NORTH);
}
class GrowAndShrinkListener implements ActionListener {
GrowAndShrinkListener(JButton button) {
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button){
button.setText("Click to shrink square");
}
}
}
}
Try This :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class frame extends JFrame
{
JButton b;
public frame()
{
setLayout(new BorderLayout());
b=new JButton("Press");
add(b,BorderLayout.SOUTH);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
b.setText("Clicked");
}
});
}
public static void main (String[] args) {
frame f=new frame();
f.setExtendedState(MAXIMIZED_BOTH);
f.setVisible(true);
}
}

How do I know if someone clicks in a specific panel?

so this is my problem. I have an 8*8 grid of panels, all white. Then, when one of them is clicked, it's supposed to change to a random color. The only problem I have right now is that I don't know how to see if the user clicked their mouse in a specific panel. Here is the code I have so far (I'm going to implement the random element afterwards)
`
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GridOfPanels extends JPanel{
int x, y;
public GridOfPanels(){
JPanel content = new JPanel(new GridLayout(8,8));
for(int i = 0; i < 64; i++){
JPanel panel = new JPanel();
panel.setBackground(Color.white);
content.add(panel);
}
this.add(content);
}
public GridOfPanels(Color backColor){
setBackground(backColor);
addMouseListener(new PanelListener());
x = 200;
y = 200;
}
private class PanelListener extends MouseAdapter{
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
repaint();
}
}
public static void main(String[] args){
JFrame theGUI = new JFrame();
theGUI.setTitle("Grid");
theGUI.setVisible(true);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theGUI.setSize(400,400);
Rectangle z = new Rectangle(x, y, 50, 50);
}
}
`
You have to add a listener to each clickable object. Here is a working example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends JFrame{
public TestFrame(int size){
JPanel content = new JPanel(new GridLayout(size, size));
JPanel[] panel = new JPanel[size * size];
PanelListener listener = new PanelListener();
for(int i = 0; i < panel.length; i++){
panel[i] = new JPanel();
panel[i].setBackground(Color.white);
panel[i].addMouseListener(listener);
content.add(panel[i]);
}
this.add(content);
}
// MouseListener offers the method mouseClicked(MouseEvent e)
private class PanelListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent event) {
/* source is the object that got clicked
*
* If the source is actually a JPanel,
* then will the object be parsed to JPanel
* since we need the setBackground() method
*/
Object source = event.getSource();
if(source instanceof JPanel){
JPanel panelPressed = (JPanel) source;
panelPressed.setBackground(Color.blue);
}
}
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent arg0) {}
#Override
public void mouseReleased(MouseEvent arg0) {}
}
public static void main(String[] args){
TestFrame theGUI = new TestFrame(8);
theGUI.setTitle("Grid");
theGUI.setVisible(true);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theGUI.setSize(400,400);
}
}
You have to add MouseListener to one of the panels. Only one panel will react to click event. In the listener cast the source to JPanel and change the color.

JButton and JLabel don't show on JDialog and sleep not work

I have a frame that when i click ok button on tester2 frame, tester1 frame should be seen and when click showbumber button, a random number should be displayed in my label.
But i can't see this generated number while i use sleep method!
Thank for help.
public class tester2 extends JFrame implements ActionListener {
public tester2() {
setTitle("Hello");
setLayout(new FlowLayout());
JButton okButton = new JButton("Ok");
okButton.addActionListener(this);
add(okButton);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(40, 50, 300, 400);
}
#Override
public void actionPerformed(ActionEvent e) {
tester1 tester1 = new tester1(tester2.this);
tester1.setVisible(true);
}
public static void main(String[] args) {
new tester2().setVisible(true);
}
}
tester 1:
public class tester1 extends JDialog implements ActionListener {
JLabel lbl1;
JButton showButton;
public tester1(JFrame owner) {
super(owner, "tester1", true);
showButton = new JButton("Show Number");
showButton.addActionListener(this);
lbl1 = new JLabel(" ");
this.add(showButton);
this.add(lbl1);
this.setBounds(40, 50, 300, 400);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == showButton) {
GenerateNumber();
tester1.this.dispose();
}
}
public void GenerateNumber() {
Random rnd1 = new Random();
try {
Thread.sleep(1000);
lbl1.setText(String.valueOf(rnd1.nextInt(100)));
} catch (InterruptedException inrptdEx) {
}
}
}
If your intention is to close the second frame automatically after a short delay, you should use a javax.swing.Timer instead.
Blocking the EDT will stop it from (amongst other things) processing repaint request, which means your UI can't be updated when you can Thread.sleep
Instead you should use a javax.swing.Timer
public void GenerateNumber() {
Random rnd1 = new Random();
try {
lbl1.setText(String.valueOf(rnd1.nextInt(100)));
} catch (InterruptedException inrptdEx) {
}
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
dispose();
}
});
timer.setRepeats(false);
timer.start();
}
I don't if your dialog shows the showButton and Label before. Because i have to add a panel in order to show them. After that you need a Timer Class to deal with auto dispose.
Your tester1 look now like this
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class tester1 extends JDialog implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
JLabel lbl1;
JButton showButton;
public tester1(JFrame owner) {
super(owner, "tester1", true);
JPanel jPanel = new JPanel();
jPanel.setLayout(new BorderLayout());
this.add(jPanel);
showButton = new JButton("Show Number");
showButton.addActionListener(this);
lbl1 = new JLabel();
jPanel.add(showButton, BorderLayout.NORTH);
jPanel.add(lbl1, BorderLayout.CENTER);
this.setBounds(40, 50, 300, 400);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == showButton) {
GenerateNumber();
}
}
public void GenerateNumber() {
Random rnd1 = new Random();
lbl1.setText(String.valueOf(rnd1.nextInt(1000000)));
Timer timer = new Timer(1000 * 1, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
dispose();
}
});
timer.setRepeats(false);
timer.start();
}
}

Categories

Resources