I'm having some trouble with a simple application I'm creating to count the number of clicks per second. The code is as follows:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.Border;
public class CPSFrame implements ActionListener {
JFrame frame;
JPanel borderPanel, settings;
JButton click;
String[] timesList = {"5","10","15","20","25","30"};
JComboBox times;
JTextField showCps;
public CPSFrame() {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
CPSFrame c = new CPSFrame();
c.drawGui();
}
});
}
public void drawGui() {
frame = new JFrame();
borderPanel = new JPanel();
settings = new JPanel();
click = new JButton("Click me!");
times = new JComboBox(timesList);
showCps = new JTextField();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("CPS Calculator");
{
borderPanel.setLayout(new BorderLayout(0, 0));
frame.add(borderPanel);
{
borderPanel.add(click);
settings.setLayout(new GridLayout(1, 0, 0, 0));
borderPanel.add(settings, BorderLayout.SOUTH);
{
settings.add(times);
settings.add(showCps);
}
}
}
frame.pack();
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent evt) {
}
}
For some reason, if I resize the JFrame and press click, both times and showCPS disappear. I have a feeling it has something to do with the way I have the BorderLayout set up, but I'm not sure.
Here is a video of what is happening.
edit: updated the code and added a video of what is happening.
Works fine for me (Java 1.6, Win) and nothing disappears after resize and click. Try to specify the location of c.click explicitly c.borderPanel.add(c.click,BorderLayout.CENTER);
Maybe there are Java implementations (platforms, versions) where BorderLayout don't like unspecified location.
Related
My JPanel and JTextField are for some reason not appearing. The programs only task is to add a number to the counter every time the button is clicked. No compiling errors nor console issues. Simply not showing up??
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Swing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
final JFrame mainFrame = new JFrame ("Counter (Program 1/2)");
mainFrame.setVisible(true);
mainFrame.setSize(400, 200);
mainFrame.setLayout(new BorderLayout());
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton countButton = new JButton("Count up");
mainFrame.add(countButton, BorderLayout.SOUTH);
countButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JTextField clicks = new JTextField(BorderLayout.CENTER);
JPanel firstPanel = new JPanel();
mainFrame.add(firstPanel);
mainFrame.add(clicks, BorderLayout.NORTH);
int counter = 1;
counter++;
String textField = String.valueOf(counter);
clicks.setText(textField);
}
});
}
});
}
}
Don't add the JTextField and JPanel inside the ActionListener. This makes no sense since you'll be re-adding new components each time the button is pressed. Instead add them on GUI creation, before calling setVisible(true) on the GUI. Then update the text field's text in the ActionListener.
As a side recommendation: try to make your class more object oriented by giving it fields, a constructor, and getting most all of that code out of the static main method.
Your mistakes:
Add clicks and firstpanel to the frame in run method, not in the actionPerformed
BorderLayout.CENTER should be pass as a parameter to add method, not to the text field constructor.
Define count as static. This is not the best way but in your situation it is the easiest way.
Call mainFrame.setVisible(true); after you added all your components.
Here is the working code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Swing {
public static int counter = 1;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JFrame mainFrame = new JFrame("Counter (Program 1/2)");
mainFrame.setSize(400, 200);
mainFrame.setLayout(new BorderLayout());
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton countButton = new JButton("Count up");
mainFrame.add(countButton, BorderLayout.SOUTH);
final JTextField clicks = new JTextField(String.valueOf(counter));
JPanel firstPanel = new JPanel();
mainFrame.add(firstPanel, BorderLayout.CENTER);
mainFrame.add(clicks, BorderLayout.NORTH);
countButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
String textField = String.valueOf(counter);
clicks.setText(textField);
}
});
mainFrame.setVisible(true);
}
});
}
}
So I have come across a peculiar problem.
My interface is just a single label, and a JSlider.
My code(stripped):
import javax.swing.*;
import java.awt.*;
public class Broken {
JLabel value = new JLabel();
JSlider slider = new JSlider(0, 255, 0);
public Broken() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel panel = new JPanel();
value.setText("Some Value");
panel.add(value);
JFrame frame = new JFrame("Frame Name");
frame.setLayout(new GridLayout(2, 1));
frame.add(panel);
frame.add(slider);
frame.pack();
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
new Broken();
}
}
What happens is the label doesn't show up. If I resize the screen from the right to the smallest possible, suddenly the text appears, and it will stay there if I resize back to what it was. I have no idea what's happening, this truly seems like a bug to me.
Before and after resizing screenshots:
Despite your efforts, you're not on the EventDispatchThread when you're creating your JLabel (or JSlider, for that matter). To test, I subclassed JLabel just see if the code was on the EDT when it's constructor is called:
import java.awt.*;
import javax.swing.*;
public class Broken {
JLabel value = new XLabel(); // called before constructor, so not on EDT
JSlider slider = new JSlider(0, 255, 0); // same here
public Broken() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel panel = new JPanel();
value.setText("Some Value");
panel.add(value);
JFrame frame = new JFrame("Frame Name");
frame.setLayout(new GridLayout(2, 1));
frame.add(panel);
frame.add(slider);
frame.pack();
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
new Broken();
}
class XLabel extends JLabel {
public XLabel() {
super();
System.out.println("EDT? " + SwingUtilities.isEventDispatchThread());
}
}
}
To fix, place the invokeLater call in main, so as to wrap the entire construction of your class onto the EDT:
import java.awt.*;
import javax.swing.*;
public class Broken2 {
JLabel value = new JLabel();
JSlider slider = new JSlider(0, 255, 0);
public Broken2() {
JPanel panel = new JPanel();
value.setText("Some Value");
panel.add(value);
JFrame frame = new JFrame("Frame Name2");
frame.setLayout(new GridLayout(2, 1));
frame.add(panel);
frame.add(slider);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Generally the proper way. Create Whole app on EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Broken2();
}
});
}
}
I need help with this code, I'm trying to make a simple cookie clicker type game, I have most the code done, but for some reason, when I try to add the JLabel to the frame, it creates an error, I was hoping one of you guys could help me out, I'm fairly new to Java, thanks for the help!
//Variables
static int clicked = 0;
private FlowLayout layout;
private Container container;
public static void main(String [] args) {
//Declaring the buttons, panels, etc...
JButton button = new JButton("Click");
JPanel panel = new JPanel();
panel.add(button);
final JFrame frame = new JFrame("Button Pressed");
frame.setSize(400, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(panel);
//Action Listener Code
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Execute when button is pressed
clicked++;
System.out.println("Button pressed " + clicked + " times!");
}
}
}
You can add an JLabel then update its text when button is clicked.
Note: call JFrame.setVisible(true) in the end when all the component is added.
sample code:
// Declaring the buttons, panels, etc...
JButton button = new JButton("Click");
final JLabel label = new JLabel();
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
clicked++;
label.setText("Button pressed " + clicked + " times!");
}
});
JPanel panel = new JPanel();
panel.add(button);
panel.add(label);
final JFrame frame = new JFrame("Button Pressed");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
Find more examples here and here
The basic principle is relatively easy. In order to add something to something else, you first need to have access (or a reference to) the thing you want to add to.
While there are a number of ways you might achieve this, the simplest might be to use an instance/class field. This field would then be accessible from anywhere within the class, for example
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ClickTest {
public static void main(String[] args) {
new ClickTest();
}
private JPanel panel;
public ClickTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
//Declaring the buttons, panels, etc...
JButton button = new JButton("Click");
panel = new JPanel();
panel.add(button);
final JFrame frame = new JFrame("Button Pressed");
frame.setSize(400, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(panel);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel.add(new JLabel("You clicked me"));
panel.revalidate();
}
});
}
});
}
}
Take a look at Creating a GUI With JFC/Swing and Understanding Class Members for more details
I'm having a problem trying to change JPanels by using buttons. I have a JFrame with 2 panels, 1 of them is for the buttons, which i want them to always be showed. The other one is the one that i will be switching everytime i press one ot the buttons of the other panel. The problem is that everytime i press them nothing really ever displays, i keep my buttons but the other panel that i call does not appear.
Code for one of the buttons is as follows
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
ReparacaoPanel r = new ReparacaoPanel(this, this.jPanel1);
this.getContentPane().remove(this.jPanel1);
this.getContentPane().add(r);
//this.setContentPane(r);
this.visiblePanel.setVisible(false);
this.visiblePanel = r;
this.pack();
this.setVisible(true);
r.setLocation(200, 200);
this.getContentPane().revalidate();
this.repaint();
}
If i try to use "this.setContentPane(r);" (it sets the frame to only show the panel) the panel shows. But when i try to call it as i'm trying to do in the code above nothing is showed apart from the panel that has the buttons.
I have no idea what i'm doing wrong, it does not seem to be a problem with the JPanel that i'm trying to call as it shows if used alone.
Anyone can help me out?
Consider this working example for switching manually between panels. Which produces this output.
.........
Some tiny NumberPanel
Every new instance shows another number in the center.
import javax.swing.JPanel;
public class NumberPanel extends JPanel {
private static int counter = 0;
public NumberPanel() {
setLayout(new BorderLayout(0, 0));
JLabel lblNewLabel = new JLabel("" + counter++);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
add(lblNewLabel);
}
}
Setting up a frame
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.SOUTH);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.getContentPane().remove(numberPanel);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();
}
});
panel.add(btnNewButton);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();
}
Testprogram
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestPanelSwitch {
private JFrame frame;
private NumberPanel numberPanel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestPanelSwitch window = new TestPanelSwitch();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public TestPanelSwitch() {
initialize();
}
private void initialize() {
// see above
}
}
Back to the Question
I think you only need to pack your frame, like in the anonymous ActionListener.
frame.getContentPane().remove(numberPanel);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();
EDIT
As leonidas mentioned it is also possible to revalidate the frame. This requires only to replace the upper call to pack by theese.
frame.invalidate();
frame.validate();
I am using a JDialog with 2 JTextfields and JButtons in it. When Jdialog opens for the first time I have a cursor on my first textfield. Now if I click somewhere outside Jdialog and then try clicking back the JDialog, I dont see the cursor on any of the textfields and I am unable to write or edit anything on the textfields.
I have set the modal to be true. So even If I click anywhere else my dialog still appears on the screen but gets deactivated.
This issue is only with linux server and not on windows. Windows works perfectly.
Adding a sample code here to get some picture of the issue.
Here TestClass is extending JFrame.
public TestClass(){
setSize(new Dimension(600,500));
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
myPanel = new JPanel();
JButton openDialog = new JButton("Click here");
openDialog.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
dialog = new JDialog(myFrame,true);
dialog.setSize(new Dimension(400,400));
JTextField myField = new JTextField(10);
JPanel innerPanel = new JPanel();
innerPanel.add(myField);
dialog.add(innerPanel);
dialog.setVisible(true);
//add(dialog);
}
});
myPanel.add(openDialog);
add(myPanel);
}
Your incomplete example could not be tested. The example below exhibits the expected behavior under Java 6 on both Mac OS X and Ubuntu 12. In particular, the text field remains functional after switching back from another program.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* #see http://stackoverflow.com/a/15576897/230513
*/
public class TestClass extends JFrame {
private static JFrame myFrame;
public TestClass() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton openDialog = new JButton("Click here");
JPanel myPanel = new JPanel();
myPanel.add(new JButton(new AbstractAction("Click here") {
#Override
public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog(myFrame, true);
JTextField myField = new JTextField(10);
JPanel innerPanel = new JPanel();
innerPanel.add(myField);
dialog.add(innerPanel);
dialog.pack();
dialog.setSize(new Dimension(160, 120));
dialog.setLocationRelativeTo(myFrame);
dialog.setVisible(true);
}
}));
add(myPanel);
pack();
setSize(new Dimension(320, 240));
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myFrame = new TestClass();
}
});
}
}