jProgressBar with Threads for Database data Insertion - java

I'm trying to implement a JprogressBar to show the data insertion progress.
Basically the user select how many data sources will be imported to database.
With this parameter the main program Start a method to list those parameters and with a foreach loop it calls the insertion Thread and the ProgressBar update Thread.
for (Maquina i : m.listar()) {
//Passing to Import Thread the object with the data and a Date parameter
ImportarDados imp = new ImportarDados(i, jDateInicial.getDate());
//Calling progress bar update Thread with the progressbar itself and progress parameter
BarraDeProgresso bp = new BarraDeProgresso(progresso, progImportacao);
imp.run();
bp.run();
}
The threads kinda work on their own, but the result is not the one I want, cause the data is being imported and the progressbar is being updated, but it is being update to 100% after all data is imported. I need to update the progress bar as long as the import thread finish the importation for each (Maquina i) object.
If it is necessary I can provide the threads code...but i don't know if this calling method can provide the result I want. Searching on the forum i found something about EDT and i think it is the problem that the bar is not being updated. Can you guys help me solving this?
Minimal and Verifiable example:
My code is pretty short. The code generated by netbeans is huge, sry for that.
That code simulate my problem. The windows is refreshed only after the for loop is finished. But the BarraDeProgresso thread is running at the same as and SysOut some info...
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
public class Minimo extends javax.swing.JFrame {
public Minimo() {
initComponents();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int progImportacao[] = {0};
progresso.setMaximum(15);
for (int i = 0; i <= 15; i++) {
ImportarDados imp = new ImportarDados(i,lblProgresso);
BarraDeProgresso bp = new BarraDeProgresso(progresso, progImportacao);
imp.run();
bp.run();
progImportacao[0] += 1;
}
}
Component Initialization (Netbeans Generated)
private void initComponents() {
progresso = new javax.swing.JProgressBar();
lblProgresso = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
lblProgresso.setText("...");
jButton1.setText("IMPORT DATA");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(60, 60, 60)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblProgresso)
.addComponent(progresso, javax.swing.GroupLayout.PREFERRED_SIZE, 382, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(47, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(191, 191, 191))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(32, 32, 32)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE)
.addComponent(lblProgresso)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(progresso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(37, 37, 37))
);
pack();
}// </editor-fold>
Runnable classes
class BarraDeProgresso implements Runnable {
public JProgressBar jProgressBar1;
public int progresso[];
public BarraDeProgresso(JProgressBar barra, int progresso[]) {
this.jProgressBar1 = barra;
this.progresso = progresso;
}
#Override
public void run() {
try {
Thread.sleep(0);
System.out.println("TBARRA PROG " + progresso[0]);
jProgressBar1.setValue(progresso[0]);
jProgressBar1.repaint();
} catch (InterruptedException e) {
}
}
}
class ImportarDados implements Runnable {
private int pi = 0;
JLabel x;
public ImportarDados(int i, JLabel tag) {
this.pi = i;
this.x = tag;
}
#Override
public void run() {
try {
Thread.sleep(500);
x.setText(Integer.toString(pi)+" /15");
} catch (InterruptedException ex) {
Logger.getLogger(Minimo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Main (Netbeans Generated)
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Minimo().setVisible(true);
}
});
}

Your current code creates no background thread. Yes you've got Runnables, but you call run() on them, meaning you are calling them on the Swing event thread. When you do this, you block the event thread, effectively freezing your program. Instead, you need to:
Create a true background thread by passing your Runnable into a Thread object's constructor and calling start() on that Thread.
Not mutate Swing components from within these background threads
Or use a SwingWorker as per the Lesson: Concurrency in Swing which will help solve both of the above issues.
For an example of use of a SwingWorker, please see:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
#SuppressWarnings("serial")
public class Minimo2 extends JPanel {
private static final int EB_GAP = 15;
private static final int PROG_BAR_WDTH = 400;
public static final int MAX_DATA = 15;
private JProgressBar progresso;
private JLabel lblProgresso;
private JButton jButton1;
private Action importDataAction = new ImportDataAction("Import Data");
public Minimo2() {
initComponents();
}
private void initComponents() {
progresso = new JProgressBar(0, MAX_DATA);
lblProgresso = new JLabel(" ");
jButton1 = new JButton(importDataAction);
int progBarHeight = progresso.getPreferredSize().height;
progresso.setPreferredSize(new Dimension(PROG_BAR_WDTH, progBarHeight));
progresso.setStringPainted(true);
JPanel btnPanel = new JPanel();
btnPanel.add(jButton1);
JPanel labelPanel = new JPanel();
labelPanel.add(lblProgresso);
JPanel progressPanel = new JPanel();
progressPanel.add(progresso);
setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(btnPanel);
add(Box.createVerticalStrut(EB_GAP));
add(labelPanel);
add(Box.createVerticalStrut(EB_GAP));
add(progressPanel);
}
private class ImportDataAction extends AbstractAction {
public ImportDataAction(String name) {
super(name); // give the button text
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic); // give it a hot key
}
#Override
public void actionPerformed(ActionEvent e) {
setEnabled(false); // disable our button
ImportDataWorker worker = new ImportDataWorker(MAX_DATA);
worker.addPropertyChangeListener(new WorkerListener());
worker.execute();
}
}
private class WorkerListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int progValue = (int) evt.getNewValue();
progresso.setValue(progValue);
String text = String.format("%02d/15", progValue);
lblProgresso.setText(text);
} else if ("state".equals(evt.getPropertyName())) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
#SuppressWarnings("rawtypes")
SwingWorker worker = (SwingWorker)evt.getSource();
try {
worker.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
progresso.setValue(MAX_DATA);
String text = String.format("%02d/15", MAX_DATA);
lblProgresso.setText(text);
importDataAction.setEnabled(true);
}
}
}
}
private class ImportDataWorker extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 500;
private int max;
public ImportDataWorker(int max) {
this.max = max;
}
#Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < max; i++) {
setProgress(i);
Thread.sleep(SLEEP_TIME);
}
return null;
}
}
private static void createAndShowGui() {
Minimo2 mainPanel = new Minimo2();
JFrame frame = new JFrame("Minimo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

Related

How to delete text from a JTextField when you press a JButton (JAVA)

My program has to print messages in the JTextField when the Resume Producers button is pressed, and it needs to delete the messages when the Resume Consumers is pressed.
The thing is that I don't know how to delete the messages when the Resume Consumers is pressed.
Code:
package buffer;
import java.util.ArrayList;
import javax.swing.JTextField;
public class Buffer
{
private String message;
private boolean full=false;
Topass pass = new Topass();
public ArrayList<String> list = new ArrayList<String> ();
JTextField tf;
String content="";
public Buffer(JTextField t1){
tf=t1;
}
public synchronized void put(String message)
{
list.add(message);
}
public synchronized void take(String message)
{
list.remove(message);
}
public synchronized void sendMessage(String msg)
{
while(full && list.size()>=30)
{
try
{
wait();
} catch (InterruptedException ex) { }
}
pass.look();
full=true;
message=msg;
list.add(message);
for(int i=0; i<list.size(); i++){
content=content+list.get(i);
}
tf.setText(content);
notifyAll();
}
public synchronized String receivesMessage()
{
while(!full)
{
try
{
wait();
} catch (InterruptedException ex) { }
}
pass.look();
full=false;
notifyAll();
return message;
}
}
package buffer;
import static java.lang.Thread.sleep;
import javax.swing.JButton;
public class Consumer extends Thread
{
private int numMessages;
private Buffer miBuffer;
private String readers;
public Consumer(String reader, Buffer miBuffer)
{
this.numMessages=numMessages;
this.miBuffer=miBuffer;
this.readers=reader;
}
#Override
public void run()
{
while(true){
try
{
sleep((int)(300+400*Math.random()));
} catch(InterruptedException e){ }
System.out.println(readers + " Has read " + miBuffer.receivesMessage());
}
}
}
package buffer;
import static java.lang.Thread.sleep;
import java.util.ArrayList;
public class Producer extends Thread
{
private String prefix;
private int numMessages;
private Buffer miBuffer;
public Producer(String prefix, int n, Buffer buffer)
{
this.prefix=prefix;
numMessages=n;
miBuffer=buffer;
}
public void run()
{
numMessages = 99;
for(int i=1; i<=numMessages; i++)
{
try
{
sleep((int)(500+400*Math.random()));
} catch(InterruptedException e){ }
miBuffer.sendMessage(prefix+i);
//miBuffer.meter(prefijo+i);
}
}
}
package buffer;
public class Topass
{
private boolean closed=false;
public synchronized void look()
{
while(closed)
{
try
{
wait();
} catch(InterruptedException ie){ }
}
}
public synchronized void open()
{
closed=false;
notifyAll();
}
public synchronized void closed()
{
closed=true;
}
}
package buffer;
import java.awt.Container;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import static jdk.nashorn.internal.objects.ArrayBufferView.buffer;
/**
*
* #author Bogdan
*/
public class DigitalBuffer extends javax.swing.JFrame
{
Buffer buffer;
Producer p;
Consumer c;
Topass paso = new Topass();
/**
* Creates new form BufferGrafico
*/
public DigitalBuffer() {
initComponents();
buffer = new Buffer(t1);
Producer A = new Producer("A",99,buffer);
Producer B = new Producer("B",99,buffer);
Producer C = new Producer("C",99,buffer);
Producer D = new Producer("D",99,buffer);
Consumer Luis = new Consumer("LUIS", buffer);
Consumer Juan = new Consumer("JUAN", buffer);
Consumer Maria = new Consumer("MARIA", buffer);
Consumer Ana = new Consumer ("ANA", buffer);
A.start();
B.start();
C.start();
D.start();
Luis.start();
Juan.start();
Maria.start();
Ana.start();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
t1 = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
JButton1 = new javax.swing.JButton();
JButton2 = new javax.swing.JButton();
JButton3 = new javax.swing.JButton();
JButton4 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
t1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
t1ActionPerformed(evt);
}
});
jLabel2.setText("Buffer content");
JButton1.setText("Stop Producers");
JButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButton1ActionPerformed(evt);
}
});
JButton2.setText("Resume Producers");
JButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButton2ActionPerformed(evt);
}
});
JButton3.setText("Stop Consumers");
JButton3.addAncestorListener(new javax.swing.event.AncestorListener() {
public void ancestorAdded(javax.swing.event.AncestorEvent evt) {
JButton3AncestorAdded(evt);
}
public void ancestorRemoved(javax.swing.event.AncestorEvent evt) {
JButton3AncestorRemoved(evt);
}
public void ancestorMoved(javax.swing.event.AncestorEvent evt) {
}
});
JButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButton3ActionPerformed(evt);
}
});
JButton4.setText("Resume Consumers");
JButton4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButton4ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(t1, javax.swing.GroupLayout.PREFERRED_SIZE, 306, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(91, 91, 91)
.addComponent(JButton1)
.addGap(80, 80, 80)
.addComponent(JButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGap(102, 102, 102))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(58, 58, 58)
.addComponent(jLabel1))
.addGroup(layout.createSequentialGroup()
.addGap(104, 104, 104)
.addComponent(JButton3)
.addGap(77, 77, 77)
.addComponent(JButton4)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(70, 70, 70)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(t1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2))
.addComponent(jLabel1))
.addGap(60, 60, 60)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(JButton1)
.addComponent(JButton2))
.addGap(34, 34, 34)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(JButton3)
.addComponent(JButton4))
.addContainerGap(64, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void t1ActionPerformed(java.awt.event.ActionEvent evt) {
}
private void JButton1ActionPerformed(java.awt.event.ActionEvent evt) {
buffer.pass.closed();
}
private void JButton2ActionPerformed(java.awt.event.ActionEvent evt) {
buffer.pass.open();
}
private void JButton3ActionPerformed(java.awt.event.ActionEvent evt) {
buffer.pass.closed();
}
private void JButton4ActionPerformed(java.awt.event.ActionEvent evt) {
}
private void JButton3AncestorAdded(javax.swing.event.AncestorEvent evt) {
// TODO add your handling code here:
}
private void JButton3AncestorRemoved(javax.swing.event.AncestorEvent evt) {
// TODO add your handling code here:
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(DigitalBuffer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(DigitalBuffer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(DigitalBuffer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(DigitalBuffer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
//</editor-fold>
//</editor-fold>
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new DigitalBuffer().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton JButton1;
private javax.swing.JButton JButton2;
private javax.swing.JButton JButton3;
private javax.swing.JButton JButton4;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JTextField t1;
// End of variables declaration
}
The thing is that i don't know how to delete the messages when the Resume Consumers is pressed
You add an ActionListener to the button. In the ActionListener you reset the text. See the section from the Swing tutorial on How to Us Buttons for more information and examples. Or, there is also a section on How to Write an ActionListener.
You can replace the text in the text field by using:
textField.setText(...);
Example #1 (Requires Java 8+):
button.addActionListener(e -> textField.setText(""));
Example #2:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText("");
}
});
In both cases, the textField will need to have been declared as final.

ActionListener class doesn't get triggered for CheckBox

I am creating this software for a project and what i did was i created a method "Salad" here what happens is user can select maximum number of 2 salads.the names of the salad are coming from the database and i created checkboxes dynamically.
This works fine and I can get the values and insert it to the database.so then what i wanted was to update the inserted row.i created a method to setselected() the all the check-boxes that user selected before. so as i told above i created this method to select maximum no of 2 check boxes .when i try to insert it works fine..but when i try to update that ActionListener does not work.
I am using setSelected(true) in constructor that ActionListener is not triggering. What should I do this in the Salad() ??
public void Salad()
{
int count =0 ;//to count rows in result set
String sql="Select name from foodmenue where type='Salad' and menue='"+selecmenue+"' ";
try {
pst=con.prepareStatement(sql);
rs=pst.executeQuery();
while(rs.next())
{
count++;
}
if(count!=0)
{
rs=pst.executeQuery();
JCheckBox [] a=new JCheckBox[count];
jPanel7.setLayout(new GridLayout());
int x=0;
while(rs.next())
{
a[x]=new JCheckBox(rs.getString("name"));
a[x].setName(rs.getString("name"));
jPanel7.add(a[x]);
a[x].setVisible(true);
a[x].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if( e.getSource() instanceof JCheckBox){
String s=((JCheckBox) e.getSource()).getName();
if(((JCheckBox) e.getSource()).isSelected())
{
if(selsalad<2)//selsalad is 0 in the bigining
{
selectedsalad[selsalad]=((JCheckBox) e.getSource()).getName();
selsalad=selsalad+1;
}
else
{
((JCheckBox) e.getSource()).setSelected(false);
showMessageDialog(null, "you cant have more than 2 salads");
}
}
if(!((JCheckBox) e.getSource()).isSelected())
{
if(selectedsalad[0].equals(s)|| selectedsalad[1].equals(s) )
{
if(selsalad<2)
{
selectedsalad[selsalad]="";
}
selsalad=selsalad-1;
showMessageDialog(null, selsalad);
}
} }
}
});
x++;
}
}
} catch (Exception e) {
showMessageDialog(null, e);
}
}
this is how i filled the check boxex
for(Component c : jPanel7.getComponents())
{
if(c instanceof JCheckBox)
{
JCheckBox temp=(JCheckBox) c;
if(temp.getName().equals(s1)){
temp.setSelected(true);
}
if(temp.getName().equals(s2)){
temp.setSelected(true);
}
}
}
MCVE : To give a better idea
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static javax.swing.JOptionPane.showMessageDialog;
public class NewJFrame extends javax.swing.JFrame {
int selsalad=0;//count of the selected checkbox this cant go more than 2
String selectedsalad[]=new String[2];
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
public NewJFrame() {
initComponents();
Salad();
showMessageDialog(null, "uncomment promlemmethod to see the probelm after you try this one");
problemmehtod();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 561, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 470, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
public void problemmehtod(){ // this is the problem now i can select any much when i call this i commented this one
for(Component c : jPanel1.getComponents())
{
if(c instanceof JCheckBox)
{
JCheckBox temp=(JCheckBox) c;
if(temp.getName().equals("a1")){
temp.setSelected(true);
}
if(temp.getName().equals("a2")){
temp.setSelected(true);
}
}
}
}
public void Salad()
{
JCheckBox a[]=new JCheckBox[5];
// int count =0 ;//to count rows in result set
try {
for(int x=0;x<5;x++)
{
jPanel1.setLayout(new GridLayout());
a[x]=new JCheckBox("a"+String.valueOf(x));
a[x].setName("a"+String.valueOf(x));
jPanel1.add(a[x]);
a[x].setVisible(true);
a[x].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if( e.getSource() instanceof JCheckBox){
String s=((JCheckBox) e.getSource()).getName();
if(((JCheckBox) e.getSource()).isSelected())
{
if(selsalad<2)
{
selectedsalad[selsalad]=((JCheckBox) e.getSource()).getName();
selsalad=selsalad+1;
}
else
{
((JCheckBox) e.getSource()).setSelected(false);
showMessageDialog(null, "you cant have more than 2 salads");
}
}
if(!((JCheckBox) e.getSource()).isSelected())
{
if(selectedsalad[0].equals(s)|| selectedsalad[1].equals(s) )
{
if(selsalad<2)
{
selectedsalad[selsalad]="";
}
selsalad=selsalad-1;
//showMessageDialog(null, selsalad);
}
}
}
}
});
}
} catch (Exception e) {
showMessageDialog(null, e);
}
}
// End of variables declaration
}
The number of check boxes selected are checked on the actionListener of each of these CheckBox. Action listeners aren't called when you are call setSelected(true) on the choice boxes.
You need to call the doClick(), if you want to call the action listeners.
JCheckBox temp=(JCheckBox) c;
if(temp.getName().equals("a1")){
temp.doClick();
}
if(temp.getName().equals("a2")){
temp.doClick();
}
Further, since both the if statements are doing the same stuff, you can just combine them.
if(temp.getName().equals("a1") || temp.getName().equals("a2")){
temp.doClick();
}
Your problem is that you're not updating the selsalad when you programmatically select a JCheckBox. Better perhaps is to get rid of the selsalad variable completely, and instead within the ActionListener iterate through an ArrayList<JCheckBox> and count exactly how many have been selected. Or make your array of JCheckBox a field, improve its name and iterate through that.
For example:
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class NewPanel extends JPanel {
private static final int CHECK_BOX_COUNT = 5;
public static final int MAX_SELECTED = 2;
private List<JCheckBox> checkBoxes = new ArrayList<>();
public NewPanel() {
setLayout(new GridLayout(0, 1));
ActionListener actionListener = new CheckBoxListener();
for (int i = 0; i < CHECK_BOX_COUNT; i++) {
String name = "a" + i;
JCheckBox checkBox = new JCheckBox(name);
checkBox.setActionCommand(name);
checkBox.addActionListener(actionListener);
add(checkBox); // add to gui
checkBoxes.add(checkBox); // add to ArrayList
}
checkBoxes.get(1).setSelected(true);
checkBoxes.get(2).setSelected(true);
}
private class CheckBoxListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int selectedCount = 0;
for (JCheckBox jCheckBox : checkBoxes) {
if (jCheckBox.isSelected()) {
selectedCount++;
}
}
if (selectedCount > MAX_SELECTED) {
Component parent = NewPanel.this;
String msg = String.format("You've selected too many checkboxes as only %d can be selected",
MAX_SELECTED);
String title = "Too Many CheckBoxes Selected";
int type = JOptionPane.ERROR_MESSAGE;
JOptionPane.showMessageDialog(parent, msg, title, type);
((JCheckBox) e.getSource()).setSelected(false);
}
}
}
public List<String> getSelectedActionCommands() {
List<String> resultList = new ArrayList<>();
for (JCheckBox checkBox : checkBoxes) {
if (checkBox.isSelected()) {
resultList.add(checkBox.getActionCommand());
}
}
return resultList;
}
private static void createAndShowGui() {
NewPanel mainPanel = new NewPanel();
int result = JOptionPane.showConfirmDialog(null, mainPanel,
"Select Options", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
System.out.println("Selected Options: " + mainPanel.getSelectedActionCommands());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

How to add JLabel to existing JTextField

I want to add Capslock label to the status JtextField. Status has got line and column values. I want to add capslock with line and column. I have tried adding updateStatus() method, but it does not work as expected.
Sample code:
public class CapsLock extends javax.swing.JFrame {
JTextField status;
int i=0;
JTextArea textArea;
JLabel capsLock;
public CapsLock() {
initComponents();
status=new JTextField();
capsLock=new JLabel();
updateStatus(1,1);
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
tabbedPane = new javax.swing.JTabbedPane();
jMenuBar1 = new javax.swing.JMenuBar();
file = new javax.swing.JMenu();
newFile = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
file.setText("File");
newFile.setText("NewFile");
newFile.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
newFileActionPerformed(evt);
}
});
file.add(newFile);
jMenuBar1.add(file);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 279, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void updateStatus(int linenumber, int columnnumber) {
status.setText("ln: " + linenumber + " Col: " + columnnumber);
}
private void newFileActionPerformed(java.awt.event.ActionEvent evt) {
final JInternalFrame internalFrame = new JInternalFrame("");
i++;
internalFrame.setName("Doc "+i);
internalFrame.setClosable(true);
internalFrame.setAutoscrolls(true);
textArea=new JTextArea();
textArea.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent ke) {
}
#Override
public void keyPressed(KeyEvent ke) {
if(Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)){
capsLock.setText("ON");
}
else{
capsLock.setText("OFF");
status.setText(capsLock.getText());
}
}
#Override
public void keyReleased(KeyEvent ke) {
}
});
textArea.addCaretListener(new CaretListener() {
#Override
public void caretUpdate(CaretEvent e) {
JTextArea editArea = (JTextArea)e.getSource();
int linenum = 1;
int columnnum = 1;
try {
int caretpos = editArea.getCaretPosition();
linenum = editArea.getLineOfOffset(caretpos);
columnnum = caretpos - editArea.getLineStartOffset(linenum);
linenum += 1;
}
catch(Exception ex) { }
updateStatus(linenum, columnnum);
}
});
status.setBackground(Color.LIGHT_GRAY);
status.setEditable(false);
internalFrame.add(textArea);
internalFrame.add(status,BorderLayout.SOUTH);
tabbedPane.add(internalFrame);
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(CapsLock.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(CapsLock.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(CapsLock.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(CapsLock.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new CapsLock().setVisible(true);
}
});
}
private javax.swing.JMenu file;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem newFile;
private javax.swing.JTabbedPane tabbedPane;
}
I write StatusPanel class as shown below:
public class StatusPanel extends JPanel{
InternalFrame currentFrame;
private JLabel statusLabel;
JLabel capsLabel;
public StatusPanel(){
statusLabel=new JLabel();
capsLabel=new JLabel();
add(statusLabel);
add(capsLabel);
updateStatus(1,1);
}
public void setRowColumn(){
currentFrame.textPane.addCaretListener(new CaretListener() {
private KeyEvent KeyEvent;
#Override
public void caretUpdate(CaretEvent e) {
int linenum = 1;
int columnnum = 1;
try {
int caretpos = currentFrame.textPane.getCaretPosition();
linenum=currentFrame.getLineAtCaret()-1;
columnnum=currentFrame.getColumnAtCaret();
linenum += 1;
}
catch(Exception ex) { }
updateStatus(linenum, columnnum);
}
});
}
private void updateStatus(int linenumber, int columnnumber)
{
statusLabel.setText("Line: " + linenumber +" "+ " Column: " + columnnumber);
}
public void setCapslock(){
currentFrame.textPane.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent ke) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void keyPressed(KeyEvent ke) {
if(Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)){
capsLabel.setText(" CAPS ON");
}
else{
capsLabel.setText(" CAPS OFF");
}
}
#Override
public void keyReleased(KeyEvent ke) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
});
}
}
In the "if" code you have a single statement. In the "else" statement you have 2 statements. Don't you think the code should be the same except for the text?
Also, you should NOT be using a text field to display the text. Instead you should be using a panel with multiple labels. One label for the row/column position. Another label for the Caps Lock status. Then you only update the text for the label that changes.
.Caps lock enable/disable not update the all the opened Documents.
Then you have a couple of solutions:
Your status bar should be common for the frame, not the Document. So the labels will be shared by all Documents. This means that whenever a Document gains focus you would need to update the caret position but the Caps Lock will still be correct from the last Document.
Or, you could create the Caps Lock field as a non-editable JTextField. Then you can share the Document of the text field with all text field. This mean when you update the text field it will be reflected on all documents.
So you would need to pass in the shared text field Document any time you create a new document for your application. Then to create the text field you would use:
JTextField textField = new JTextField( sharedDocument );
Edit:
When you create the component for the frame you would have code something like:
StatusPanel status = new StatusPanel();
frame.add(status, ...);
Then in this custom class you add the components to display the data you want displayed. You also need to add methods like setRowColumn(...) and setCapsLock(...) to display the text you want to see for those components.
Then you need to create another custom class MyInternalFrame that extend JInternalFrame. Then when you create this class you use:
MyInternalFrame internal = new MyInternalFrame(status);
So now your custom internal frame has access to the status bar and you can update the status bar from any Document that your create.
Another Edit:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class Status extends JPanel
{
public Status()
{
setLayout( new BorderLayout() );
StatusPanel status = new StatusPanel();
add(status, BorderLayout.SOUTH);
DocumentPanel document = new DocumentPanel( status );
add(document, BorderLayout.CENTER);
}
class StatusPanel extends JPanel
{
JLabel caretStatus = new JLabel("Caret Offset: 0");
public StatusPanel()
{
add( caretStatus );
}
public void updateCaretStatus(String status)
{
caretStatus.setText( status );
}
}
class DocumentPanel extends JPanel
{
private StatusPanel status;
private JTextArea textArea;
public DocumentPanel(StatusPanel statusPanel)
{
status = statusPanel;
textArea = new JTextArea(5, 30);
add( new JScrollPane( textArea ) );
textArea.addCaretListener( new CaretListener()
{
#Override
public void caretUpdate(CaretEvent e)
{
status.updateCaretStatus( "Caret Offset: " + textArea.getCaretPosition() );
}
});
}
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Status");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new Status() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

jLabel slideshow when a mouse enters a button

I can't get this to work:
public void ru() throws InterruptedException {
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/adv/room.jpg")));
setVisible(true);
Thread.sleep(400);
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/adv/ROOMS.jpg")));
setVisible(true);
Thread.sleep(400);
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/adv/background.jpg")));
setVisible(true);
}
private void BtnRoomsMouseEntered(java.awt.event.MouseEvent evt) {
try {
ru();
} catch (InterruptedException ex) {
}
}
Any solutions?
I want a jLabel to show a slide show when a mouse enters a certain button and stays like that as long as the mouse is still in a button. If the mouse happens to exit the button, the jlabel will return to a null state. (no more anything.) Is that possible? Please help. I also tried using for statement but no good. I'm using netbeans by the way.
First thing you need to implement a javax.swing.Timer. Trying to call Thread.sleep() will block the Event Dispatch Thread. See How to use Swing Timers. Here is the basic construct
Timer(int delay, ActionListener listener)
where delay is the time in milliseconds you want delayed and the listener will listen for the Timer ActionEvent fired every delay milliseconds.
So you want something like this
public class MyFrame extends javax.swing.JFrame {
private Timer timer = null;
ImageIcon[] icons = new ImageIcon[3];
int index = -1;
public MyFrame() {
initComponents();
icons[0] = new ImageIcon(...);
icons[1] = new ImageIcon(...);
icons[2] = new ImageIcon(...);
timer = new Timer(2000, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (index + 1 > 2) {
index = 0;
jLabel3.setIcon(icons[index]);
} else {
index++;
jLabel3.setIcon(icons[index]);
}
}
});
}
}
For your button, you need to use mouseEntered and mouseExited, then you can just call timer.start() or timer.stop()
private void jButton1MouseExited(MouseEvent e) {
timer.stop();
}
private void jButton1MouseEntered(MouseEvent e) {
timer.start();
}
If you don't know how to add the MouseListener just right click on the button from the design view and select Event -> Mouse -> mouseEntered. Do the same for mouseExited. You should see the above methods auto-generated for you.
UPDATE
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class ImageViewer extends javax.swing.JFrame {
private Timer timer = null;
ImageIcon[] icons = new ImageIcon[5];
int index = -1;
public ImageViewer() {
initComponents();
try {
icons[0] = new ImageIcon(new URL("http://www.iconsdb.com/icons/preview/orange/stackoverflow-4-xxl.png"));
icons[1] = new ImageIcon(new URL("http://www.iconsdb.com/icons/preview/caribbean-blue/stackoverflow-4-xxl.png"));
icons[2] = new ImageIcon(new URL("http://www.iconsdb.com/icons/preview/royal-blue/stackoverflow-4-xxl.png"));
icons[3] = new ImageIcon(new URL("http://www.iconsdb.com/icons/preview/moth-green/stackoverflow-4-xxl.png"));
icons[4] = new ImageIcon(new URL("http://www.iconsdb.com/icons/preview/soylent-red/stackoverflow-4-xxl.png"));
} catch (MalformedURLException ex) {
Logger.getLogger(ImageViewer.class.getName()).log(Level.SEVERE, null, ex);
}
timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index + 1 > 4) {
index = 0;
jLabel1.setIcon(icons[index]);
} else {
index++;
jLabel1.setIcon(icons[index]);
}
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new JButton();
jLabel1 = new JLabel();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("jButton1");
jButton1.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent evt) {
jButton1MouseEntered(evt);
}
public void mouseExited(MouseEvent evt) {
jButton1MouseExited(evt);
}
});
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(127, 127, 127))
.addGroup(layout.createSequentialGroup()
.addGap(27, 27, 27)
.addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 285, GroupLayout.PREFERRED_SIZE)
.addContainerGap(29, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(22, 22, 22)
.addComponent(jLabel1, GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(jButton1)
.addGap(16, 16, 16))
);
pack();
}// </editor-fold>
private void jButton1MouseEntered(MouseEvent evt) {
timer.start();
}
private void jButton1MouseExited(MouseEvent evt) {
timer.stop();
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ImageViewer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ImageViewer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(ImageViewer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ImageViewer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ImageViewer().setVisible(true);
}
});
}
// Variables declaration - do not modify
private JButton jButton1;
private JLabel jLabel1;
// End of variables declaration
}
You want to add a MouseAdapter to the JLabel and use its mouseEntered() and mouseExited() as follows:
jLabel3.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(java.awt.event.MouseEvent evt) {
try {
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/adv/room.jpg")));
setVisible(true);
Thread.sleep(400);
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/adv/ROOMS.jpg")));
setVisible(true);
Thread.sleep(400);
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/adv/background.jpg")));
setVisible(true);
} catch(InterruptedException e) {
}
#Override
public void mouseExited(java.awt.event.MouseEvent evt) {
//whatever you mean by "null state"
}
});

How to make a Java serialized object being passed over network notify client GUI of change

I am making a client-server Java app that is going to be MV(C, P) like. My current problem is once the client get's a Player object it needs to tell the GUI that the Player was changed and it should update everything on GUI. (Not too detailed, so entire update shouldn't be bad)
/*
* ClientGUI.java
*
* Created on Dec 10, 2009, 7:51:31 PM
*/
package inequity;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Administrator
*/
public class ClientGUI extends javax.swing.JFrame
{
private Socket socClient;
private ObjectOutputStream socketOut;
private ObjectInputStream socketIn;
PriorityBlockingQueue<Command> clientQ = null;
private Player me;
public ClientGUI()
{
initComponents();
setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
clientQ = new PriorityBlockingQueue<Command>(Server.CLIENT_QUEUE_SIZE, new CompObj());
me = new Player();
}
public void initPlayer(String name, String color)
{
me.name = name;
me.color = color;
}
public boolean connect(int port)
{
try
{
socClient = new Socket("127.0.0.1", port);
if(socClient.isConnected())
System.out.println("Connected");
socketOut = new ObjectOutputStream(socClient.getOutputStream());
socketIn = new ObjectInputStream(socClient.getInputStream());
socketOut.writeObject(new PlayerUpdate(me, 2));
new ClientListener(socketIn).start();
}
catch(Exception e)
{
try
{
if(socketOut != null)
{
socketOut.flush();
socketOut.close();
}
if(socketIn != null)
{
socketIn.close();
}
System.out.println("Unable to connect");
}
catch (IOException ex)
{
System.out.println("IOException caught");
return false;
}
}
return true;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
txtMsg = new javax.swing.JTextField();
btnSend = new javax.swing.JButton();
PlayerName = new javax.swing.JLabel();
ID = new javax.swing.JLabel();
chat = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
txtMsg.setText("Test");
txtMsg.setName("txtMsg"); // NOI18N
txtMsg.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtMsgActionPerformed(evt);
}
});
btnSend.setText("Send");
btnSend.setName("btnSend"); // NOI18N
btnSend.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSendActionPerformed(evt);
}
});
PlayerName.setText("N/A");
PlayerName.setName("PlayerName"); // NOI18N
ID.setText("ID:");
ID.setName("ID"); // NOI18N
chat.setText("Chatbox");
chat.setName("chat"); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnSend, javax.swing.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE)
.addComponent(txtMsg, javax.swing.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE)
.addComponent(PlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE))
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addComponent(ID)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 62, Short.MAX_VALUE)
.addComponent(chat)
.addGap(41, 41, 41))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(ID)
.addComponent(chat))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(PlayerName)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(txtMsg, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnSend)
.addContainerGap())
);
pack();
}// </editor-fold>
private void txtMsgActionPerformed(java.awt.event.ActionEvent evt) {
}
private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {
try
{
if(socketOut != null)
socketOut.writeObject(new ChatCmd(txtMsg.getText(), 10));
}
catch (IOException ex)
{
Logger.getLogger(ClientGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run()
{
String name = "";
String color = "";
JoinGUI join = new JoinGUI(name, color);
ClientGUI client = new ClientGUI();
client.initPlayer(name, color);
client.setVisible(join.prompt());
client.connect(1345);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel ID;
private javax.swing.JLabel PlayerName;
private javax.swing.JButton btnSend;
private javax.swing.JLabel chat;
private javax.swing.JTextField txtMsg;
// End of variables declaration
// End of variables declaration
public class ClientListener extends Thread
{
private ObjectInputStream recieving;
public ClientListener(ObjectInputStream in)
{
recieving = in;
}
#Override
public void run()
{
Command cmd;
while(true)
{
try
{
cmd = (Command) recieving.readObject();
clientQ.add(cmd);
//temp code! Put in clientProxy? Drop to clientQ?
clientQ.take().exec(me);
ID.setText("" + me.getID());
PlayerName.setText("" + me.name);
chat.setText(me.latestChatMsg);
}
catch (InterruptedException ex)
{
Logger.getLogger(ClientGUI.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex)
{
Logger.getLogger(ClientListener.class.getName()).log(Level.SEVERE, null, ex);
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(ClientListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
package inequity;
import java.io.Serializable;
import java.util.ArrayList;
/**
*
* #author Administrator
*/
public class Player implements Serializable
{
public ArrayList openHandShakes;
public String latestChatMsg;
private int ID;
public String name;
public String color;
public Player()
{
openHandShakes = new ArrayList();
ID = -1;
name = "";
color = "";
}
public void setID(int id)
{
ID = id;
}
public int getID()
{
return ID;
}
public void openHandShake(int shakeID)
{
openHandShakes.add(shakeID);
}
public boolean closeHandShake(int shakeID)
{
return true;
}
public void latestChat(String message)
{
latestChatMsg = message;
}
}
package inequity;
import javax.swing.Box;
import javax.swing.JTextField;
/**
*
* #author Administrator
*/
public class JoinGUI extends javax.swing.JFrame
{
private JTextField nameBox;
private JTextField colorBox;
public JoinGUI(String name, String color)
{
//give back name and color to clientgui
nameBox = new JTextField("Enter Name");
colorBox = new JTextField("Enter Color");
Box inputMenu = Box.createVerticalBox();
inputMenu.add(nameBox);
inputMenu.add(colorBox);
add(inputMenu);
}
public boolean prompt()
{
setVisible(false);
//wait for enter to be pressed then return true, as clientGUI is waiting to started
//then give name and color to client
return true;
}
}
/*
* Server.java
*/
package inequity;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import java.net.*;
import java.util.concurrent.PriorityBlockingQueue;
/**
* The main class of the application.
*/
public class Server extends JFrame
{
public static final int CLIENT_QUEUE_SIZE = 10;
public static final int SERVER_QUEUE_SIZE = 10;
public Server()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public PlayerProxy wait4client(int playerID, ServerSocket server, PriorityBlockingQueue<Command> srvQ)
{
Socket incoming;
PriorityBlockingQueue<Command> clientQ = null;
Runnable rIn;
Runnable rOut;
Thread tIn = null;
Thread tOut = null;
try
{
incoming = server.accept();
clientQ = new PriorityBlockingQueue<Command>(CLIENT_QUEUE_SIZE, new CompObj());
rIn = new Net2QRunnable(playerID, incoming, srvQ);
rOut = new Q2NetRunnable(playerID, incoming, clientQ);
tIn = new Thread(rIn);
tOut = new Thread(rOut);
tIn.start();
tOut.start();
}
catch (Exception e)
{
e.printStackTrace();
}
clientQ.add(new HelloMsg());
return new PlayerProxy(playerID, tIn, tOut, clientQ);
}
public static void main(String[] args)
{
PriorityBlockingQueue<Command> srvQ = new PriorityBlockingQueue<Command>(SERVER_QUEUE_SIZE, new CompObj());
try
{
Game game = new Game(srvQ);
Server srv = new Server();
ServerSocket server = new ServerSocket(1345);
srv.setVisible(true);
System.out.println("Lobby");
while (game.numPlayers() < 2)
{
game.addPlayer(srv.wait4client(game.numPlayers(), server, srvQ));
}
game.play();
System.out.println("Game Finished");
}
catch (SocketException e)
{
System.out.println("Socket already taken, exiting.");
}
catch (Exception ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I can provide full source if you'd like, but I think that's all that's needed.
Again, a Player object get's sent to the client, which accepts and sets it's Player object to the received one. I want client's Player to say, "Hey GUI! I just got modified. Lemme call an update method that extracts/parses all my data!"
Any help would be appreciated.
UPDATE:
public class ClientListener extends Thread
{
private ObjectInputStream recieving;
public ClientListener(ObjectInputStream in)
{
recieving = in;
}
#Override
public void run()
{
Command cmd;
while(true)
{
try
{
cmd = (Command) recieving.readObject();
clientQ.add(cmd);
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
clientQ.take().exec(me);
if(me.changed == true)
updateGUI();
}
catch (Exception ex)
{
Logger.getLogger(ClientGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
catch (Exception ex)
{
Logger.getLogger(ClientListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Seems like it should be what I want right?
Use SwingUtilities.invokeLater to run a handler in the GUI thread.
Just put your update code in a Runnable instance and pass it to SwingUtilities.InvokeLater(). That will put your runnable into the event dispatch queue
Or you could call invokeAndWait to block until the update is complete.
If you try to call code that updates Swing elements in another thread, it can cause instability in the rest of your code.

Categories