I have an undecorated JFrame with my own 'header' at the top. It works fine except for telling if the window is out of focus.
I've tried things like
if(!frame.hasFocus()
//Do stuff here
But this obviously won't work when I have other components in the window, such as a JTextField. I haven't found a way to do this so any help is appreciated.
Here is a sample code by which you can implement it:
import java.awt.event.FocusListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class SwingTest {
public static void main(String args[])
{
swing();
}
public static void swing()
{
JFrame g= new JFrame("First");
g.setVisible(true);
g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g.setSize(300, 300);
g.setLayout(null);
JLabel l=new JLabel("Times Windows Lost Focus : 0");
l.setBounds(20,10, 200, 60);
g.add(l);
g.addWindowFocusListener( new WindowFocusListener() {
int c=0;
#Override
public void windowLostFocus(WindowEvent e) {
c++;
}
#Override
public void windowGainedFocus(WindowEvent e) {
l.setText("Times Windows Lost Focus :"+c);
//System.out.println(c);
// TODO Auto-generated method stub
}
});;
}
}
Related
Found a simple JComboBox sample on java2 and expanded it to include both a DocumentListener and KeyListener
hoping to capture keystrokes done within the JComboBox.
Eventually those keystrokes will be captured to display the data which matches the keys entered.
For example, as the user types APP, all records beginning with A is return then AP is return and then all data beginning with APP. Basically doing a Filter on "APP*".
But for now, I am unable to get either a KeyListener or DocumentListener working.
Actually, it works sporadically and can't narrow down why. It seems to only work for the Enter key but would like for it to capture for all keystrokes.
Here is the code.
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ComboBoxEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.metal.MetalFileChooserUI;
public class JComboBoxFilter extends JPanel implements ItemListener {
public JComboBoxFilter () {
JComboBox jc = new JComboBox();
jc.addItem("A");
jc.addItem("AA");
jc.addItem("AAA");
jc.addItem("C");
jc.addItem("CC");
jc.addItem("CCC");
jc.addItem("B");
jc.addItem("BB");
jc.addItem("BBB");
jc.addItemListener(this);
add(jc);
ComboBoxEditor editor = jc.getEditor();
JTextField textField = (JTextField)editor.getEditorComponent();
textField.addKeyListener(new KeyListener()
{
#Override
public void keyPressed(KeyEvent arg0) {
runThisKeyListener();
}
#Override
public void keyReleased(KeyEvent arg0) {
runThisKeyListener();
}
#Override
public void keyTyped(KeyEvent arg0) {
runThisKeyListener();
}
private void runThisKeyListener()
{
System.out.println("Inside runThisKeyListener() : " + textField.getText());
}
});
DocumentListener textFieldDL = new DocumentListener()
{
#Override
public void insertUpdate(DocumentEvent e)
{
runThis();
}
#Override
public void removeUpdate(DocumentEvent e)
{
runThis();
}
#Override
public void changedUpdate(DocumentEvent e)
{
runThis();
}
private void runThis()
{
System.out.println("Inside runThis() : " + textField.getText());
}
};
textField.getDocument().addDocumentListener(textFieldDL);
}
public void itemStateChanged(ItemEvent ie) {
String s = (String)ie.getItem();
System.out.println(s);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new JComboBoxFilter ());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
Is there anything wrong with the code or is there a Java rule or restriction not allowing this type of functionality?
I have created a Java application that goes through hundreds of documents after user clicks "Run" button. Is there a way to terminate the program and leave the GUI running? All I want to be able to stop is the process of reading the documents.
System.exit(0) is not the solution I am looking for as my whole app closes.
It's difficult to say something without to see your application. But probably this piece of code will help you to understand how to implement what you want:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
public class SwingWorkerTest implements Runnable {
private JButton cancelButton = new JButton("Cancel");
private JButton runButton = new JButton("Run");
private JLabel label = new JLabel("Press 'Run' to start");
private LongWorker longWorker;
#Override
public void run() {
JFrame frm = new JFrame("Long task test");
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
cancelButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
longWorker.terminate();
}
});
runButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
longWorker = new LongWorker();
runButton.setEnabled(false);
cancelButton.setEnabled(true);
label.setText("Task in progress. Press 'Cancel' to terminate.");
longWorker.execute();
}
});
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
bottomPanel.add(runButton);
bottomPanel.add(cancelButton);
frm.add(label);
frm.add(bottomPanel, BorderLayout.SOUTH);
frm.setSize(400, 200);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new SwingWorkerTest());
}
private class LongWorker extends SwingWorker<Void, Void> {
private volatile boolean terminated;
#Override
protected Void doInBackground() throws Exception {
// check special variable tov determine whether this task still active
for (int i = 0; i < 1000 && !terminated; i++) {
readFile();
}
return null;
}
#Override
protected void done() {
if (terminated) {
label.setText("Process terminated. Press 'Run' to restart.");
} else {
label.setText("Process done. Press 'Run' to restart.");
}
cancelButton.setEnabled(false);
runButton.setEnabled(true);
}
// dummy method - make 10 milliseconds sleep
private void readFile() {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
// Nothing here
}
}
public void terminate() {
terminated = true;
}
}
}
I've got a problem with my program what I can't solve. I'm trying for hours and tried to google, etc... I've seen many programs, which is working, but I don't know why my solution does not. My goal (for now) is simple, I want to write to the cmd-line in case of a mouse click or a key press. The first one works, but the second is not. Can anyone tell my why?
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class test {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
test window = new test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public test() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.getContentPane().addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("Mouse has clicked!");
}
});
frame.getContentPane().addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent arg0) {
System.out.println("A key has pressed.");
}
});
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Well, finally I had enough time trying to find the solution and now I'm discovered it. I do not know why, but it was not possible to add a keyListener to the JFrame. I could only add for a JButton or a JTextField, etc... This is strange for me, a little bit :c
Java noob here. My Swing class that extends JDialog does not dispose when the user presses the Windows Close button - java.exe stays in memory. I've stripped the code right down to this shell, I still get this behaviour.
I took a look at other samples, such as at Basic Java Swing, how to exit and dispose of your application/JFrame
When I commented out the two System.exit(0) lines in that sample code, the class in that sample still disposed correctly. What am I missing to make my class dispose?
import javax.swing.JFrame;
import javax.swing.JDialog;
public class WhyNoDispose extends JDialog{
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
WhyNoDispose frame = new WhyNoDispose("my title");
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
frame.setVisible(true);
//System.exit(0);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
public WhyNoDispose(String title) {
super(new JFrame(title), ModalityType.APPLICATION_MODAL);
pack();
}
}
You're creating a JFrame and never disposing it here:
public WhyNoDispose(String title) {
super(new JFrame(title), ModalityType.APPLICATION_MODAL); // *********
pack();
}
So since the JFrame is alive and a GUI has been rendered, the Swing event thread keeps on running.
If you instead make the JFrame behave so that the program exits on JFrame close, and then explicitly dispose of the JFrame, your program now exits:
import java.awt.Window;
import javax.swing.JFrame;
import javax.swing.JDialog;
public class WhyNoDispose extends JDialog {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
WhyNoDispose frame = new WhyNoDispose("my title");
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
JFrame win = (JFrame) frame.getOwner();
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
win.dispose();
// System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public WhyNoDispose(String title) {
super(new JFrame(title), ModalityType.APPLICATION_MODAL);
pack();
}
}
But this is very kludgy code, to say the least -- what if the owning window isn't a JFrame? What if it's null?
Another solution is to use no JFrame at all, so that when the JDialog is disposed, there's no persisting window left over to make the event thread persist:
import java.awt.Window;
import javax.swing.JFrame;
import javax.swing.JDialog;
public class WhyNoDispose extends JDialog {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
WhyNoDispose frame = new WhyNoDispose("my title");
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public WhyNoDispose(String title) {
super((JFrame)null, title);
pack();
}
}
I am making an app that will have some 'rectangles' (myLabel) with a text (rectangleName). Whenever I click on that rectangle, a combobox (nameComboBox) is shown to change the name of it.
So this is the declaration of that class.
public class myLabel extends JLabel implements MouseListener,FocusListener{
//this.panel;
JComboBox nameComboBox;
String rectangleName;
I added some focus stuff to that class as you can see it implements FocusListener.
I want to show the combobox only when the recangle is focused and hide it otherwise. The problem that I have is that when I select a rectangle and it shows the combobox because it's focused, when I click on the combobox, the rectangle loses its focus so it hides the combobox. Any way to prevent this?
Edit:
Replying to #mKorbel, This is my SSCCE
import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class MyJLabel extends JLabel implements MouseListener,FocusListener{
JComboBox nameComboBox;
JPanel mainPanel;
String name;
public MyJLabel() {
this.setLocation(10,10);
this.setBounds(20, 20,200,200);
this.setBackground(Color.LIGHT_GRAY);
this.setFocusable(true);
setOpaque(true);
setHorizontalAlignment(SwingConstants.CENTER);
setFont(getFont());
setText(this.name);
this.nameComboBox= new JComboBox(new String[] { "option1","option2","option3" });
this.nameComboBox.setBounds(40,40,100,50);
this.nameComboBox.setVisible(false);
this.addMouseListener(this);
this.addFocusListener(this);
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("focus gained");
this.nameComboBox.setVisible(true);
}
#Override
public void focusLost(FocusEvent e) {
System.out.println("focus lost");
this.nameComboBox.setVisible(false);
}
#Override
public void mouseClicked(MouseEvent e) {
this.requestFocus();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
MyJLabel myjl=new MyJLabel();
JFrame fr = new JFrame();
fr.setLayout(null);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComboBox otherCombo = new JComboBox(new String[] { "otherOption1","otherOption2","otherOption3" });
otherCombo.setBounds(40,400,100,50);
fr.add(myjl.nameComboBox);
fr.add(myjl);
fr.add(otherCombo);
fr.setSize(300,500);
fr.setVisible(true);
}
}
You must start clicking on the combo at the bottom and you'll see in the console that the focus is lost. click on the gray rectangle and the focus will be gained. Click on the combo inside the rectangle and the rectangle will lose and gain the focus instantly, so it's impossible to choose an item. I would like to not change the focus of the rectangle while I am interacting with its combobox.