Java JFrame not updating settings of a button - java

I am currently having a minor issue with a Java Jframe and a button not updating.
I am trying to disable the Print Button until the printing of the new JFrame it opens is done and that JFrame is closed...
The button will only disable if and when a new window occurs, but will not until then, which can take a little bit of time....
I set the button to disable by doing this: PrintBttn.setEnabled(false);
I have tried calling mainPanel.revalidate(); mainPanel.repaint(); PrintBttn.revalidate(); PrintBttn.repaint as well as a mixture of the above as they recommended in other forums...
I am kind of lost at the moment on this and to why it is not disabling the button until a new window appears since the first thing i do is Disable it as shown above, and then go through and create the new window....
Thanks,
Erik

Most likely, it's a question of releasing the EDT to allow it to repaint the disabled button.
Generally, it will look something like this:
PrintBttn.setEnabled(false);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Code to display the second JFrame goes here
}
};

Might be you had failed to put your first frame in the EDT too, do watch the code, is this what you actually want :
import java.awt.event.*;
import javax.swing.*;
public class TwoFrames
{
private JFrame frame1, frame2;
private JPanel panel1, panel2;
private JButton button1, button2, button3;
private ActionListener action;
public TwoFrames()
{
frame1 = new JFrame("Frame One");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2 = new JFrame("Frame Two");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel1 = new JPanel();
action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (ae.getSource() == button1)
{
// Here goes your code for displaying your Second Frame.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if (!frame2.isShowing())
{
panel2 = new JPanel();
button2 = new JButton("Click Me to HIDE FRAME.");
button2.setHorizontalTextPosition(AbstractButton.CENTER);
button2.setVerticalTextPosition(AbstractButton.CENTER);
button2.addActionListener(action);
panel2.add(button2);
panel2.setOpaque(true);
frame2.setContentPane(panel2);
frame2.setSize(200, 200);
frame2.setLocationRelativeTo(null);
frame2.setVisible(true);
}
}
});
button3.setEnabled(false);
}
else if (ae.getSource() == button2)
{
frame2.dispose();
button3.setEnabled(true);
}
}
};
button1 = new JButton("Click Me to Display FRAME.");
button1.setHorizontalTextPosition(AbstractButton.CENTER);
button1.setVerticalTextPosition(AbstractButton.CENTER);
button1.addActionListener(action);
button3 = new JButton("Watch Me getting DISABLED");
button3.setHorizontalTextPosition(AbstractButton.CENTER);
button3.setVerticalTextPosition(AbstractButton.CENTER);
button3.addActionListener(action);
panel1.add(button1);
panel1.add(button3);
panel1.setOpaque(true);
frame1.setContentPane(panel1);
frame1.setSize(200, 200);
frame1.setVisible(true);
}
public static void main(String... args)
{
// Here we are Scheducling a JOB for Event Dispatcher Thread.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TwoFrames();
}
});
}
}

Related

Why is my showMessageDialog displaying twice?

I am working on a simple counter swing app. I'm trying to make it so when you click the check box, it will stay on the top and display a message dialog being "On Top" or "Not On Top".
However, when I click the checkbox after compiling and running, both of the messages display, and after clicking OK on both messages, the checkbox isn't even enabled. If I were to remove the showMessageDialog, it would still function properly, but I want to learn how to appropriately implement this.
Thank you in advance. Here is all of the code for the program:
public Class Counter {
JFrame frame;
JPanel panel;
JButton button, clear;
JTextField textC;
JLabel label;
JCheckBox cbox;
boolean topC = false;
int icount = 0;
String scount;
String topStatus = "";
public Counter() {
gui();
setActions();
}
public void gui() {
frame = new JFrame("Counter Program");
panel = new JPanel();
label = new JLabel("Counter");
textC = new JTextField();
textC.setPreferredSize(new Dimension(72,28));
textC.setEditable(false);
button = new JButton("Click");
clear = new JButton("Clear");
cbox = new JCheckBox("Top");
frame.setSize(350,80);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(panel);
panel.add(label);
panel.add(textC);
panel.add(button);
panel.add(clear);
panel.add(cbox);
frame.setVisible(true);
}
public void setActions() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
icount++;
scount = Integer.toString(icount);
textC.setText(scount);
}
});
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
icount = 0;
textC.setText("");
}
});
cbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
topC = !topC;
if (topC) {
topStatus = "Top";
}
else topStatus = "Not Top";
frame.setAlwaysOnTop(topC);
JOptionPane.showMessageDialog(frame, topStatus, "Top Setting", 1);
}
});
}
public static void main(String[]args) {
new Counter();
}
}
An ItemListener generates two events, one for the selection and one for the unselection (and vice versa). Read the section from the Swing tutorial on How to Write an ItemListener for more information and working exmaples if you really want to use an ItemListener.
Otherwise, use an ActionListener instead, it will only generate a single event.

How to be back on main class panel from panels of different class?

I have two classes one is main class and other is pro class. The main class has introductory panel which further shows the panel of pro class. The second panel of pro class has "Home" button which needs to show the main class panel. please tell me how do I make "Home" button work?
class proMain extends JPanel {
JPanel pan2 = new JPanel();
JButton b1, b2, b3;
CardLayout lay = new CardLayout();
public void pshow() {
// First Panel
pan.setBackground(Color.red);
b1 = new JButton("Next");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("Next")) {
pan2.setVisible(true);
pan.setVisible(false);
}
}
});
pan.add(b1);
// Second Panel
b2 = new JButton("Previous");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("Previous")) {
pan.setVisible(true);
pan2.setVisible(false);
}
}
});
b3 = new JButton("Home");
b3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand() == "Home") {
//
}
}
});
pan2.setBackground(Color.cyan);
pan2.add(b2);
pan2.add(b3);
pan.setVisible(true);
pan2.setVisible(false);
add(pan);
add(pan2);
}
}
Above class is proMain class and the main class is:
public class proDis {
public static void main(String[] args) {
JFrame fr = new JFrame("CrdLay");
JPanel pan3 = new JPanel();
JButton b = new JButton("Next");
CardLayout cl = new CardLayout();
fr.setLayout(cl);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("Next")) {
pan3.setVisible(false);
proMain pm = new proMain();
pm.pshow();
pm.setLayout(cl);
fr.add(pm);
pm.setVisible(true);
}
}
});
pan3.setBackground(Color.gray);
pan3.add(b);
fr.setSize(100, 300);
fr.setVisible(true);
fr.add(pan3);
}
}
You are attempting to use a CardLayout, which is the correct approach. However, your implementation is incorrect.
The problem with your code is that you are not using the methods of the CardLayout to control which panel is being displayed. The CardLayout supports methods. like next(...) and previous(...) to sequentially move through all the panels and the method show(...) to display a specific panel.
So the first thing to do is give your panels a name when you add each panel to the layout. Then change your code to use the above methods to control which panel is being displayed. There is no need to play with the visibility of any panel, this is the job of the CardLayout.
Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.

Hide radio button on show jframe

I'm using netbeans 8. I have 2 radio button that I want to hide when the frame is shown. How can I do that? I successfully do that when I click other button such as this:
private void jRadioButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
jRadioButton3.setVisible(false);
jRadioButton4.setVisible(false);
}
but that's not what I want. I want to set it to invisible and only show it when I click other radio button. For some reason netbean prevent me from editing certain area in my source code so I can't test or explore it. Please help and thanks in advance.
Set the JRadioButton setVisible method as false by default and then change it when an action is performed.
For example, here under, the JRadioButtons will be visible once the first JRadioButton is selected. If it is deselected, they disappear.
I did it with a JRadioButton but it can be done with other components of course.
Solution
public class Test extends JFrame{
private JRadioButton but1, but2, but3;
public Test(){
setSize(new Dimension(200,200));
initComp();
setVisible(true);
}
private void initComp() {
but1 = new JRadioButton();
but1.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
but2.setVisible(but1.isSelected());
but3.setVisible(but1.isSelected());
}
});
but2 = new JRadioButton();
but2.setVisible(false);
but3 = new JRadioButton();
but3.setVisible(false);
setLayout(new FlowLayout());
JPanel pan = new JPanel();
pan.add(but1);
pan.add(but2);
pan.add(but3);
getContentPane().add(pan);
}
public static void main(String[] args) {
new Test();
}
}
You can set the radio button to invisible when you add it to the frame and make it visible on some event:
public class InvisibleRadioButton {
public static void main(String[] args) {
JFrame frame = new JFrame();
final JRadioButton jRadioButton1 = new JRadioButton("1");
JRadioButton jRadioButton2 = new JRadioButton("2");
frame.setLayout(new FlowLayout());
frame.add(jRadioButton1);
frame.add(jRadioButton2);
frame.setVisible(true);
jRadioButton1.setVisible(false); // initialize as invisible
jRadioButton2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jRadioButton1.setVisible(true); // set it to be visible
}
});
frame.pack();
}
}

How do I hide the current JPanel and show a new one with a button in Java?

I unfortunately have to use multiple windows in this program and I don't think CardLayout is going to work because I can't have any buttons constant between the different layouts. So I'm trying to code a button to hide the present JPanel (thePanel) and show a new one (thePlacebo).
I'm trying to hide thePanel in an ActionListener like this:
frame.getContentPane().remove(thePanel);
I thought this would work, but it just freezes my program as soon as I hit the button.
Here's a chunk of the code for context:
public class Reflexology1 extends JFrame{
JButton button1, button2;
JButton movingButton;
JTextArea textArea1;
int buttonAClicked, buttonDClicked;
private long _openTime = 0;
private long _closeTime = 0;
JPanel thePanel = new JPanel();
JPanel thePlacebo = new JPanel();
final JFrame frame = new JFrame("Reflexology");
public static void main(String[] args){
new Reflexology1();
}
public Reflexology1(){
frame.setSize(600, 475);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Reflexology 1.0");
frame.setResizable(false);
button1 = new JButton("Accept");
button2 = new JButton("Decline");
movingButton = new JButton("Click Me");
ListenForAcceptButton lForAButton = new ListenForAcceptButton();
ListenForDeclineButton lForDButton = new ListenForDeclineButton();
button1.addActionListener(lForAButton);
button2.addActionListener(lForDButton);
//movingButton.addActionListener(lForMButton);
JTextArea textArea1 = new JTextArea(24, 50);
textArea1.setText("Tracking Events\n");
textArea1.setLineWrap(true);
textArea1.setWrapStyleWord(true);
textArea1.setSize(15, 50);
FileReader reader = null;
try {
reader = new FileReader("EULA.txt");
textArea1.read(reader, "EULA.txt");
} catch (IOException exception) {
System.err.println("Problem loading file");
exception.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException exception) {
System.err.println("Error closing reader");
exception.printStackTrace();
}
}
}
JScrollPane scrollBar1 = new JScrollPane(textArea1, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
AdjustmentListener listener = new MyAdjustmentListener();
thePanel.add(scrollBar1);
thePanel.add(button1);
thePanel.add(button2);
thePlacebo.add(movingButton);
frame.add(thePanel);
ListenForWindow lForWindow = new ListenForWindow();
frame.addWindowListener(lForWindow);
frame.setVisible(true);
}
// Implement listeners
private class ListenForAcceptButton implements ActionListener{
public void actionPerformed(ActionEvent e){
if (e.getSource() == button1){
Calendar ClCDateTime = Calendar.getInstance();
System.out.println(ClCDateTime.getTimeInMillis() - _openTime);
_closeTime = ClCDateTime.getTimeInMillis() - _openTime;
frame.getContentPane().remove(thePanel);
}
}
}
Does anybody know what I might be doing wrong?
After removing components from a container, it goes into the invalidate state. To bring it back to the valid state you have to revalidate and repaint that. In your case you are directly adding/removing components from JFrame so depending on the Java version you can do this :
frame.revalidate(); // For Java 1.7 or above
frame.getContentPane().validate(); // For Java 1.6 or below
frame.repaint();
Here is one working example for your help :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Assignment
{
private JFrame frame;
private JPanel firstPanel;
private JPanel secondPanel;
private JButton forwardButton;
private JButton backButton;
private void displayGUI()
{
frame = new JFrame("Assignment");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.setOpaque(true);
firstPanel.setBackground(Color.BLUE);
secondPanel = new JPanel();
secondPanel.setOpaque(true);
secondPanel.setBackground(Color.RED);
forwardButton = new JButton("Forward");
forwardButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
frame.remove(firstPanel);
frame.add(secondPanel);
frame.revalidate(); // For Java 1.7 or above.
// frame.getContentPane().validate(); // For Java 1.6 or below.
frame.repaint();
}
});
backButton = new JButton("Back");
backButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
frame.remove(secondPanel);
frame.add(firstPanel);
frame.revalidate(); // For Java 1.7 or above.
// frame.getContentPane().validate(); // For Java 1.6 or below.
frame.repaint();
}
});
firstPanel.add(forwardButton);
secondPanel.add(backButton);
frame.add(firstPanel);
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Assignment().displayGUI();
}
});
}
}
correct way could be (only) by using CardLayout
otherwise have to remove JPanel from container and to call (as last code line and call only one times after all changes for container are done)
.
myJPanelsContainer#revalidate(); // in Java6 for JFrame validate()
myJPanelsContainer#repaint();

Default button in JFrame is not firing when the enter key is being pressed

I have a JFrame with three JButtons on it. I have set txtSearch (a JTextField component) to have the focus when JFrame loads. One of the buttons is set as the default button. This is my code:
private void formWindowOpened(java.awt.event.WindowEvent evt)
{
// btnRefresh.setMnemonic(KeyEvent.VK_R); // Even if this line
// is not commented, but
// still the event wouldn't fire.
this.getRootPane().setDefaultButton(btnRefresh);
}
When it loads, the button is just selected, but it did nothing when the Enter key was being pressed. How do I correctly implement it?
btnRefresh.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnRefreshActionPerformed(evt);
}
});
private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {
JOptionPane.showMessageDialog(this, "Pressed!");
// Other codes here (Replace by JOptionPane)
}
What component has focus when the JFrame comes up? I ask because some components "eat" the Enter key event. For example, a JEditorPane will do that.
Also, when you assign an ActionListener to JTextField, the ActionListener will be called instead of the DefaultButton for the root pane. You must choose either to have an ActionListener or a DefaultButton, but you can't have both fire for the same JTextField. I'm sure this applies to other components as well.
I don't see what you are doing incorrectly from what is posted. Here is a short example that works. Perhaps it will reveal something useful to you.
import java.awt.BorderLayout;
public class ExampleFrame extends JFrame
{
private JPanel m_contentPane;
private JTextField m_textField;
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
ExampleFrame frame = new ExampleFrame();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ExampleFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
m_contentPane = new JPanel();
m_contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
m_contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(m_contentPane);
m_textField = new JTextField();
m_contentPane.add(m_textField, BorderLayout.NORTH);
m_textField.setColumns(10);
JButton btnNewButton = new JButton("Default");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(ExampleFrame.this, "Default.");
}
});
m_contentPane.add(btnNewButton, BorderLayout.CENTER);
JButton btnNewButton_1 = new JButton("Not default");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(ExampleFrame.this, "Not default.");
}
});
m_contentPane.add(btnNewButton_1, BorderLayout.WEST);
m_textField.requestFocus();
getRootPane().setDefaultButton(btnNewButton);
}
}

Categories