Can't dispose JFrame inside Thread - java

I have a class that extends Thread and inside this class I have a JFrame. I need to dispose this JFrame without finalizing the system, like we do with System.exit(0).
When I create and initialize the frame, it has a name like "frame0" but then, when I call it's name on the ActionListener, it shows "frame1", even if the JFrame class is final or static.
public class RegisterExercise extends Thread {
private final JFrame frame;
private JButton btnSave;
private JPanel mainPanel;
private JButton btnCancel;
private JTextField txtName;
private JTextField txtEasyName;
private JTextField txtDescription;
private JTextField txtMachineName;
private JLabel lblName;
private JLabel lblEasyName;
private JLabel lblDescription;
private JLabel lblMachineName;
public RegisterExercise() {
frame = new JFrame("Register an exercise");
btnCancel.addActionListener(e -> {
System.out.println("Frame:" + frame.getName());
frame.dispose();
});
}
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException |
UnsupportedLookAndFeelException e) {
throw new RuntimeException(e);
}
initializeFrame(frame);
super.run();
}
private void initializeFrame(JFrame frame) {
frame.setContentPane(new RegisterExercise().mainPanel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.println("This is frame:" + frame.getName());
}
}
This class is called from another Thread that I created, I'll share here the class that calls this Thread class
public class Menu extends Thread {
private JButton btnExit;
private JPanel mainPanel;
private JButton btnRegisterExercise;
private JTable menuTable;
private JLabel lblVersion;
// JFrames
private RegisterExercise registerExercise;
public Menu() {
// Exit Button
btnExit.addActionListener(e -> {
int answer = JOptionPane.showConfirmDialog(null, "Do you want do leave?", "Leaving", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION) {
System.exit(0);
}
});
// Register Exercise Button
btnRegisterExercise.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (registerExercise == null) {
registerExercise = new RegisterExercise();
registerExercise.start();
}
}
});
}
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException |
UnsupportedLookAndFeelException e) {
throw new RuntimeException(e);
}
JFrame frame = new JFrame("My Move Gym");
frame.setContentPane(new Menu().mainPanel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
super.run();
}
}

Related

JFrame and while loop

How do I break a while loop if I click on my jframe shutdown? I 'm making a clicker that needs to be stopped at some point, but it'll just continue clicking even tho the exit has been pressed.
public class ClickWindow {
private JFrame frame;
private static Clicker click;
private static long currTime;
private static long totalTime;
private JTextField textField;
private static int textFieldValue = 0;
private static Boolean Bool = true;
/**
* Launch the application.
*/
public static void main(String[] args) throws InterruptedException {
click = new Clicker();
ClickWindow window = new ClickWindow();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ClickWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setBounds(100, 100, 289, 90);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnNewButton_1 = new JButton("Press Space");
btnNewButton_1.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
Bool = false;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
if(textFieldValue == 0){
textFieldValue = 250;
}
try {
while (Bool) {
click.click();
textFieldValue = Integer.parseInt(textField.getText());
Thread.sleep(textFieldValue);
}
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
btnNewButton_1.setBounds(10, 25, 110, 23);
frame.getContentPane().add(btnNewButton_1);
textField = new JTextField();
textField.setBounds(127, 25, 141, 23);
frame.getContentPane().add(textField);
textField.setColumns(10);
}
public void windowClosing(WindowEvent event) {
Bool = false;
}
}
Clicker class
public class Clicker{
public static void click() throws AWTException{
Robot bot = new Robot();
bot.mousePress(InputEvent.BUTTON1_MASK);
bot.mouseRelease(InputEvent.BUTTON1_MASK);
}
}
Edited with the full code.
You should define the defaultCloseOperation for your JFrame:
JFrame myFrame = new JFrame("MyFrame");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
If you set the defaultCloseOperation, hitting the close button will trigger a call to System exit:
public static void main(String[] args)
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
JFrame myFrame = new JFrame("MyFrame");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//...add components here
myFrame.pack();
myFrame.setVisible(true);
}
catch (Exception e)
{
System.exit(-1);
}
}
});
}
If you want to shutdown the entire application you can just do this:
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
This will shutdown your application after the Jframe was closed.
You can also call System.exit(0) in your windowClosing method or whenever you want to shutdown your application
instead of adding the keyListener to your JButton try having your JFrame, i.e. ClickWindow implement it. I think this would work.

How to create a instance

I am having two classes, a main class and class which extends JPanel and implements Runnable. I am trying to create two threads for the same instance of the JPanel class in an actionListener, but i just don't know where to create the JPanel1 object...
//Edit: Button1 is the start of the application .After that , button 2 will appear with a quick animation of labels and when clicked it(button2) will start the same animation too. How can i do whenever one of these buttons is clicked to launch the run method ?
public void run() {
if(isTom){
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
panel.removeAll();
panel.add(tomLabel1);
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
panel.add(tomLabel2);
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
panel.add(tomLabel3);
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
panel.add(tomLabel4);
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
panel.add(tomLabel5);
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
panel.removeAll();
repaint();
revalidate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
public Game(){
JFrame frame = new JFrame();
Panel1 key = new Panel1();
key.addKeyListener(key);
frame.add(key);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setVisible(true);
}
public static void main(String[] args) {
new Game();
}
public class Panel1 extends JPanel implements KeyListener,Runnable{
JButton button1 = new JButton("BUTTON1");
JButton button2 = new JButton("BUTTON2");
add(button1);add(button2);
Thread t = new Thread(this); // This works, but i need it inside the actionListener.
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("button1");
Thread x = new Thread(j);//'j' is an JPanel1 object. I need something like this i guess
x.setName("Thread x");});
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("button2");
Thread y = new Thread(j);
y.setName("Thread y");
});
public void run(){
System.out.println(Thread.currentThread().getName());
}
First, Swing is NOT thread safe! This means that you should NEVER create or modify the UI from outside of context of the Event Dispatching Thread!
Second, Swing is a single threaded environment, this means that you should never block or execute long running code from within the context of the Event Dispatching Thread, this will cause the UI to freeze until the block is removed.
Your concept is correct, you implementation is wrong, you should use a Swing Timer instead.
Instead of removing and adding labels, use a single label and change it's properties (text/icon, what ever)
See Concurrency in Swing and How to use Swing Timers for more details
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
try {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException exp) {
exp.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
private JButton button1;
private JButton button2;
private SplashScreen splashScreen;
public TestPane() throws IOException {
button1 = new JButton("Button One");
button2 = new JButton("Button Two");
JPanel buttons = new JPanel();
buttons.add(button1);
buttons.add(button2);
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
splashScreen.run();
}
});
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
splashScreen.run();
}
});
splashScreen = new SplashScreen();
setLayout(new BorderLayout());
add(splashScreen);
add(buttons, BorderLayout.SOUTH);
}
}
public static class SplashScreen extends JPanel {
protected static final int IMAGE_COUNT = 4;
private JLabel label;
private Timer timer;
private int delta;
private int count;
private Icon[] icons;
private Dimension preferredSize;
public SplashScreen() throws IOException {
String path = "/images/splash";
String ext = ".png";
icons = new Icon[IMAGE_COUNT];
int maxWidth = 0;
int maxHeight = 0;
for (int index = 0; index < IMAGE_COUNT; index++) {
String name = path + (index + 1) + ext;
System.out.println(name);
icons[index] = new ImageIcon(ImageIO.read(getClass().getResource(name)));
maxWidth = Math.max(maxWidth, icons[index].getIconWidth());
maxHeight = Math.max(maxHeight, icons[index].getIconHeight());
}
preferredSize = new Dimension(maxWidth, maxHeight);
timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (count >= IMAGE_COUNT) {
count = IMAGE_COUNT - 2;
delta = -1;
} else if (count < 0) {
((Timer)e.getSource()).stop();
} else {
label.setIcon(icons[count]);
count += delta;
}
}
});
setLayout(new BorderLayout());
label = new JLabel();
add(label);
}
#Override
public Dimension getPreferredSize() {
return preferredSize;
}
public void run() {
if (!timer.isRunning()) {
delta = 1;
count = 0;
timer.start();
}
}
}
}
Create a new instance of a Thread with your Panel1 class instance:
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("button1");
Thread x = new Thread(Panel1.this);
x.start();
x.setName("Thread x");});
Repeat for the other button with a new Thread object:
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("button2");
Thread y = new Thread(Panel1.this);
y.start();
y.setName("Thread y"); });
Panel1.this is referring to the instance of the Panel1 class that is currently running, making sure that your Threads are executing run() of that instance.

Closing a runnable JOptionPane

I have this Runnable window:
EventQueue.invokeLater(new Runnable(){
#Override
public void run() {
op = new JOptionPane("Breaktime",JOptionPane.WARNING_MESSAGE);
dialog = op.createDialog("Break");
dialog.setAlwaysOnTop(true);
dialog.setModal(true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
}
});
Is it possible that I can have a timer here to close this within 1 or 2 minutes instead of clicking the OK button?
Yes, the trick would be to get the Timer started before you call setVisible...
public class AutoClose02 {
public static void main(String[] args) {
new AutoClose02();
}
private Timer timer;
private JLabel label;
private JFrame frame;
public AutoClose02() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JOptionPane op = new JOptionPane("Breaktime", JOptionPane.WARNING_MESSAGE);
final JDialog dialog = op.createDialog("Break");
dialog.setAlwaysOnTop(true);
dialog.setModal(true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// Wait for 1 minute...
timer = new Timer(60 * 1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
timer.setRepeats(false);
// You could use a WindowListener to start this
timer.start();
dialog.setVisible(true);
}
}
);
}
}

Change the look and feel of java application on runtime (IDE: Netbeans)

I am building a java app and I want to change the theme(look and feel) of application at runtime with these radio buttons. I do not know how to do this!
Thanks in advance!
You can do that by calling SwingUtilities.updateTreeComponentUI(frame) and passing container component. Be aware that it won't be efficient always. So something like this:
public static void changeLaf(JFrame frame) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
}
This method changes current LaF to systems.
EDIT:
Changing LaF via JRadioMenuItem demo:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class LafDemo {
public static void changeLaf(JFrame frame, String laf) {
if (laf.equals("metal")) {
try {
UIManager.setLookAndFeel(UIManager
.getCrossPlatformLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
if (laf.equals("nimbus")) {
try {
UIManager
.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
if (laf.equals("system")) {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
SwingUtilities.updateComponentTreeUI(frame);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton btnDemo = new JButton("JButton");
JSpinner spnDemo = new JSpinner();
JComboBox<String> cmbDemo = new JComboBox<String>();
cmbDemo.addItem("One");
cmbDemo.addItem("Two");
cmbDemo.addItem("Three");
JMenuBar mBar = new JMenuBar();
frame.setJMenuBar(mBar);
JMenu mnuLaf = new JMenu("Look and feel");
JRadioButtonMenuItem mniNimbus = new JRadioButtonMenuItem(
"Nimbus");
JRadioButtonMenuItem mniMetal = new JRadioButtonMenuItem(
"Metal");
JRadioButtonMenuItem mniSystem = new JRadioButtonMenuItem(
"Systems");
ButtonGroup btnGroup = new ButtonGroup();
btnGroup.add(mniNimbus);
btnGroup.add(mniMetal);
btnGroup.add(mniSystem);
mBar.add(mnuLaf);
mnuLaf.add(mniNimbus);
mnuLaf.add(mniMetal);
mnuLaf.add(mniSystem);
mniNimbus.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "nimbus");
}
});
mniMetal.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "metal");
}
});
mniSystem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "system");
}
});
DefaultTableModel model = new DefaultTableModel(
new Object[][] {}, new String[] { "First", "Second" });
model.addRow(new Object[] { "Some text", "Another text" });
JTable table = new JTable(model);
panel.add(btnDemo);
panel.add(spnDemo);
panel.add(cmbDemo);
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
You simply need to use the UIManager.LookAndFeelInfo[] to store the available LookAndFeel, then use UIManager.setLookAndFeel(LookAndFeelClassName) to set and after this do call SwingUtilities.updateComponentTreeUI(frameReference)
EDIT :
Do call pack on JFrame/JWindow/JDialog(parent container) at the end, as very much specified by the Swing Lord #AndrewThompson.
Please have a look at this small example :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LookAndFeelDemo {
private JFrame frame;
private JButton button;
private int counter;
private Timer timer;
private JLabel lafNameLabel;
private UIManager.LookAndFeelInfo[] lafs;
public LookAndFeelDemo() {
lafs = UIManager.getInstalledLookAndFeels();
counter = 0;
}
private ActionListener eventActions = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == timer) {
counter %= lafs.length;
try {
UIManager.setLookAndFeel(lafs[counter].getClassName());
} catch(Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
lafNameLabel.setText(lafs[counter++].getName());
frame.pack();
} else if (ae.getSource() == button) {
if (timer.isRunning()) {
timer.stop();
button.setText("Start");
} else {
timer.start();
button.setText("Stop");
}
}
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
lafNameLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
button = new JButton("Stop");
button.addActionListener(eventActions);
contentPane.add(lafNameLabel);
contentPane.add(button);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
timer.stop();
}
});
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, eventActions);
timer.start();
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new LookAndFeelDemo().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
EDIT 2 :
Updating the code example to include adding LookAndFeels from JRadioButtonMenuItem on the fly. Though please, be advised, it would be much better if you use Action instead of an ActionListener, I used it only to incorporate the changes in the previous code :-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LookAndFeelDemo {
private JFrame frame;
private JButton button;
private int counter;
private Timer timer;
private JLabel lafNameLabel;
private ButtonGroup bg;
private JRadioButtonMenuItem[] radioItems;
private UIManager.LookAndFeelInfo[] lafs;
public LookAndFeelDemo() {
lafs = UIManager.getInstalledLookAndFeels();
counter = 0;
}
private ActionListener eventActions = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == timer) {
counter %= lafs.length;
try {
UIManager.setLookAndFeel(lafs[counter].getClassName());
} catch(Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
lafNameLabel.setText(lafs[counter++].getName());
frame.pack();
} else if (ae.getSource() == button) {
if (timer.isRunning()) {
timer.stop();
button.setText("Start");
} else {
timer.start();
button.setText("Stop");
}
} else if (ae.getSource() instanceof JRadioButtonMenuItem) {
JRadioButtonMenuItem radioItem = (JRadioButtonMenuItem) ae.getSource();
String lafName = radioItem.getActionCommand();
System.out.println("LAF Name : " + lafName);
for (int i = 0; i < radioItems.length; i++) {
if (lafName.equals(radioItems[i].getActionCommand())) {
setApplicationLookAndFeel(lafs[i].getClassName());
}
}
}
}
private void setApplicationLookAndFeel(String className) {
try {
UIManager.setLookAndFeel(className);
} catch (Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
lafNameLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
button = new JButton("Start");
button.addActionListener(eventActions);
contentPane.add(lafNameLabel);
contentPane.add(button);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
timer.stop();
}
});
frame.setJMenuBar(getMenuBar());
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, eventActions);
}
private JMenuBar getMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu lookAndFeelMenu = new JMenu("Look And Feels");
bg = new ButtonGroup();
radioItems = new JRadioButtonMenuItem[lafs.length];
for (int i = 0; i < radioItems.length; i++) {
radioItems[i] = new JRadioButtonMenuItem(lafs[i].getName());
radioItems[i].addActionListener(eventActions);
bg.add(radioItems[i]);
lookAndFeelMenu.add(radioItems[i]);
}
menuBar.add(lookAndFeelMenu);
return menuBar;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new LookAndFeelDemo().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
Well, considering Nimbus is currently selected, I am going to assume that you want to change the LAF to Nimbus? If so, you will need to do this:
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
If you want to see all of the LAFs that are currently installed, you could use UIManager.getInstalledLookAndFeels();. For more information, consider reading this
Here's mine:
You should call this method when a Action event occurs when the user clicks on a JMenuItem or something else of your choice.
private void changeLookAndFeel() {
final LookAndFeelInfo[] list = UIManager.getInstalledLookAndFeels();
final List<String> lookAndFeelsDisplay = new ArrayList<>();
final List<String> lookAndFeelsRealNames = new ArrayList<>();
for (LookAndFeelInfo each : list) {
lookAndFeelsDisplay.add(each.getName());
lookAndFeelsRealNames.add(each.getClassName());
}
if (lookAndFeelsDisplay.size() != lookAndFeelsRealNames.size()) {
throw new InternalError();
}
String changeSpeed = (String) JOptionPane.showInputDialog(this, "Choose Look and Feel Here\n(these are all available on your system):", "Choose Look And Feel", JOptionPane.QUESTION_MESSAGE, null, lookAndFeelsDisplay.toArray(), null);
boolean update = false;
if (changeSpeed != null && changeSpeed.length() > 0) {
for (int a = 0; a < lookAndFeelsDisplay.size(); a++) {
if (changeSpeed.equals(lookAndFeelsDisplay.get(a))) {
try {
UIManager.setLookAndFeel(lookAndFeelsRealNames.get(a)); //re update with correct class name String
this.whichLookAndFeel = changeSpeed;
update = true;
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
err.println(ex);
ex.printStackTrace();
Logger.getLogger(Starfighter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
if (update) {
int width = 800;
int height = 625;
if (UIManager.getLookAndFeel().getName().equals("CDE/Motif")) {
height += 12;
}
this.setSize(width, height);
this.menuBar.updateUI();
this.menuBar = new JMenuBar();
menuBar.updateUI();
this.setJMenuBar(menuBar);
}
}

How to update the JTextField when the variable value is changed?

I have two Java(.java) files. One has a JButton and JTextField and the other has a Thread. In first Java file, I have added an ActionListener to the JButton so that, when the button is pressed, a thread (object for 2nd .java file in created and thread is initiated) runs which modifies an integer variable continuously. How to display the value of that integer variable (of 2nd .java file) in the JTextField (of 1st .java file) ?
Detection.java
package sample;
public class Detection implements Runnable
{
public String viewers;
public int count;
public void run()
{
try
{
while (true)
{
// i have written code for displaying video.
// and it say how many no. of people in the video
// the no of people is stored in a variable "count"
viewers=""+count; //storing count as string so as to display in the JTextField
}
}
catch (Exception e)
{
System.out.println("Exception: "+e);
}
}
}
UsrInterfac.java
//build using WindowBuilder eclipse juno
package sample;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class UsrInterfac
{
private JFrame frame;
private JTextField textField;
Detection dd = new Detection();
Thread th = new Thread(dd);
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
UsrInterfac window = new UsrInterfac();
window.frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public UsrInterfac()
{
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize()
{
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnStartThread = new JButton("Start Thread");
btnStartThread.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
th.start();
}
});
btnStartThread.setBounds(59, 133, 117, 23);
frame.getContentPane().add(btnStartThread);
textField = new JTextField();
textField.setBounds(270, 134, 104, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
}
}
Starting from the basics, while using Swing, it is always best to use LayoutManagers, which can make your work much more easier, in comparison to using Absolute Positioning.
Whenever one needs to change something in the View from some another thread, it is always advisable to do that using EventQueue.invokeLater(...)/EventQueue.invokeAndWait(...).
This small sample program, might be able to help you get an idea, how to accomplish what you so desire :-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ThreadCounter
{
private CustomThread cThread;
private JTextField tField;
private JButton button;
private int counter;
public ThreadCounter()
{
counter = 0;
}
private void displayGUI()
{
JFrame frame = new JFrame("Thread Counter Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
tField = new JTextField(10);
tField.setText("0");
button = new JButton("Start");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter == 0)
{
cThread = new CustomThread(tField);
cThread.setFlagValue(true);
cThread.start();
counter = 1;
button.setText("Stop");
}
else
{
try
{
cThread.setFlagValue(false);
cThread.join();
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
counter = 0;
button.setText("Start");
}
}
});
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new ThreadCounter().displayGUI();
}
});
}
}
class CustomThread extends Thread
{
private int changingVariable;
private JTextField tField;
private boolean flag = true;
public CustomThread(JTextField tf)
{
changingVariable = 0;
tField = tf;
}
public void setFlagValue(boolean flag)
{
this.flag = flag;
}
#Override
public void run()
{
while (flag)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
tField.setText(
Integer.toString(
++changingVariable));
}
});
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
System.out.println("I am OUT of WHILE");
}
}
Ideally you should post your code. Anyway, when you are calling the thread code, either pass the instance of the first class (object) or an instance of JTextField, so that the thread can set the new value in the text field.

Categories