So I'm working on a project with JFrames. When the programm starts it creates a JFrame in a Method called "initialThread" and then it sets the bounds, Default Close Operation and the visibility in a Method called "initialize".
When debugging the Method "initialThread", the frame automaticaly becomes visible without me excecuting the "initialize" Method.
The Code where I run the Methods:
public void loadPanels(){
initialThread();
initialize();
}
Here's the code with the two Methods i was talking about:
public void initialThread(){
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
try {
frame = new JFrame();
frame.setAlwaysOnTop (true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* set the basic functions and configurations of the frame.
*/
private void initialize() {
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
Related
I know there are already lot of thread available for this topic. I have already visited almost all of em, this one, this one, this one, also this one and this one.But didn't solve my issue.
My problem is different over here when I try to restore the JFrame it blinks, and didn't come on top of everything. I have already run this code in Ubuntu and it worked like a charm on ubuntu. frame.setAlwaysOnTop(true); works absolutely fine on ubuntu.
To solve this issue in windows I tried to use WindowsListener,
But in windows 7 it blinks and didn't come on top of every windows. What I think is that it's trying to come on top of everything but may be other application has higher priority than this it goes away. How can I resolve this issue ?
EDIT :
I have two thread over here one thread is authenticating and if it's authenticated it minimized. If not authenticated it should always be on top for authenticating. Even if user switches window by pressing Alt key tab it should again come on top after 2 seconds.
Code for authentication :
public class ScreenLockAndUnlock implements Runnable{
public static JFrame frame;
public static boolean working = false;
private JTextField punch;
public void stop(){
working = false;
}
public void run(){
try{
frame = new JFrame("Protected");
frame.setContentPane(new JLabel(new ImageIcon("C:\\Users\\four.four-PC\\eclipse-workspace\\optimization\\src\\main\\java\\com\\greycode\\optimization\\finger_PNG6297.png")));
frame.setVisible(true);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
gs.setFullScreenWindow(frame);
frame.validate();
frame.setLayout(new BorderLayout());
punch = new JTextField();
frame.add(punch,BorderLayout.SOUTH);
punch.requestFocus();
punch.addActionListener(action);
}finally{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
private void onTop() throws AWTException{
// TODO Auto-generated method stub
AlwaysOnTop top = new AlwaysOnTop();
new Thread(top).start();
while(true){
try{
frame.setState(Frame.NORMAL);
if(punch.getText().trim()!= null && punch.getText().trim().toLowerCase().equals("true")){
working = true;
top.cancel();
frame.setState(JFrame.ICONIFIED);
Thread.sleep(10000);
top.star();
top = new AlwaysOnTop();
new Thread(top).start();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
#SuppressWarnings("serial")
Action action = new AbstractAction(){
public void actionPerformed(ActionEvent e){
try{
onTop();
} catch (AWTException e1){
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
}
This code always look for whether JFrame is on top or not if not authenticated
public class AlwaysOnTop implements Runnable{
boolean cancelled = false;
public void run(){
while(!cancelled){
try{
lookForMinimised();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void cancel(){
this.cancelled = true;
}
public void star(){
this.cancelled = false;
}
public void lookForMinimised() throws InterruptedException{
// TODO Auto-generated method stub
ScreenLockAndUnlock.frame.addWindowStateListener(new WindowStateListener(){
public void windowStateChanged(WindowEvent e){
// TODO Auto-generated method stub
int newState = e.getNewState();
if((newState & Frame.ICONIFIED) == Frame.ICONIFIED){
System.out.println("Frame is minimised");
ScreenLockAndUnlock.frame.setAlwaysOnTop(false);
ScreenLockAndUnlock.frame.setAlwaysOnTop(true);
ScreenLockAndUnlock.frame.setVisible(true);
ScreenLockAndUnlock.frame.toFront();
ScreenLockAndUnlock.frame.requestFocus();
ScreenLockAndUnlock.frame.validate();
ScreenLockAndUnlock.frame.setState(Frame.NORMAL);
}
else if ((newState & Frame.NORMAL) == Frame.NORMAL){
System.out.println("Waiting for authentication ...");
}
}
});
Thread.sleep(2000);
}
}
Main method:
public class Authenticate{
public static void main(String[] args){
Thread displayScreen = new Thread(new ScreenLockAndUnlock());
displayScreen.start();
}
}
Please find a code which depicts the logical functionality that you want.
Also note that this code just depicts the functionality only which are frame restore-minimize, thread and their inter-working.
At the end, it will be you, who have to use the same at appropriate locations as per your need.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Frame;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
public class TestClass2 extends JFrame {
private JPanel contentPane;
private JTextField textField;
static boolean isAuthenticationStarted = false;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestClass2 frame = new TestClass2();
frame.setVisible(true);
frame.addWindowStateListener(new WindowStateListener() {
public void windowStateChanged(WindowEvent e) {
// minimized
if ((e.getNewState() & Frame.ICONIFIED) == Frame.ICONIFIED){
if (!isAuthenticationStarted)
{
// Authentication not started yet and window minimized
frame.setState(Frame.NORMAL);
}
}
// // maximized
// else if ((e.getNewState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH){
//
// }
}
});
frame.setAlwaysOnTop(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TestClass2() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
textField = new JTextField();
textField.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER)
{
new Thread()
{
public void run()
{
// Start authentication here
isAuthenticationStarted = true;
// if authentication is success show next jframe
// else restore window
// reset the flag only when authentication is successful
// isAuthenticationStarted = false;
// Minimizing frame
setState(Frame.ICONIFIED);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// restoring frame
setState(Frame.NORMAL);
}
}.start();
}
}
});// End listener
contentPane.add(textField, BorderLayout.CENTER);
textField.setColumns(10);
}
}
Hope this will help you. :-)
I want to update my look and feel by JRadioButtonMenuItem. And I searching in Stackoverflow but what I find was a big bunch of code in 1 class. For me as a beginner its easier to seperate function in a special class.
That is my Frame-Class.
public class CalenderFrame extends JFrame {
public CalenderFrame() throws HeadlessException {
createFrame();
}
public void createFrame() {
setJMenuBar(CalenderMenuBar.getInstance().createMenu());
setTitle("Calender");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(400, 300));
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
And that is my MenueBar Class. I just give a short one of Code that is specific for this question. This class is an Singleton.
public JMenuBar createMenu() {
JMenu lookAndFeelMenu = new JMenu("Look & Feel");
JRadioButtonMenuItem lAndFWindowsItem = new JRadioButtonMenuItem("Windows",true);
lAndFWindowsItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == lAndFWindowsItem) {
lAndFAction(1);
}
}
});
JRadioButtonMenuItem lAndFMetalItem = new JRadioButtonMenuItem("Metal",false);
lAndFMetalItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == lAndFMetalItem) {
lAndFAction(2);
}
}
});
JRadioButtonMenuItem lAndFMotifItem = new JRadioButtonMenuItem("Motif", false);
lAndFMotifItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == lAndFMotifItem) {
lAndFAction(3);
}
}
});
ButtonGroup group = new ButtonGroup();
group.add(lAndFWindowsItem);
group.add(lAndFMetalItem);
group.add(lAndFMotifItem);
lookAndFeelMenu.add(lAndFWindowsItem);
lookAndFeelMenu.add(lAndFMetalItem);
lookAndFeelMenu.add(lAndFMotifItem);
}
public void lAndFAction(int counter) {
try {
String plaf = "";
if (counter == 1) {
plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
} else if (counter == 2) {
plaf = "javax.swing.plaf.metal.MetalLookAndFeel";
} else if (counter == 3) {
plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
}
UIManager.setLookAndFeel(plaf);
//SwingUtilities.updateComponentTreeUI(this);
} catch (UnsupportedLookAndFeelException ue) {
System.err.println(ue.toString());
} catch (ClassNotFoundException ce) {
System.err.println(ce.toString());
} catch (InstantiationException ie) {
System.err.println(ie.toString());
} catch (IllegalAccessException iae) {
System.err.println(iae.toString());
}
}
}
I hope you guys can help me.
I'm not sure what your problem actually is. But, you must update your components after changing the LaF. According to the Look and Feel Documentation:
Changing the Look and Feel After Startup
You can change the L&F with setLookAndFeel even after the program's
GUI is visible. To make existing components reflect the new L&F,
invoke the SwingUtilities updateComponentTreeUI method once per
top-level container. Then you might wish to resize each top-level
container to reflect the new sizes of its contained components. For
example:
UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
Therefore, you would need a reference to the frame holding the components in your UI. An idea would be doing something like:
public class CalendarMenuBar {
// Add this field to tour factory
private static JFrame frameThatWillBeUpdated;
// ... (Your code goes here)
// update this method to receive the reference of the frame which will
// need to be refreshed (update the GUI)
public JMenuBar createMenu(JFrame frame) {
// sets the reference for the frame
frameThatWillBeUpdated = frame;
// ... (the rest of your code for this method)
}
// ...
// Update this method to refresh the frame
public void lAndFAction(int counter) {
try{
// ... (your code)
// Set the LaF
UIManager.setLookAndFeel(plaf);
// Update the component tree (frame and its children)
SwingUtilities.updateComponentTreeUI(frameThatWillBeUpdated);
// repack to resize
frame.pack();
} catch(Exception ex){
// Your catches
}
}
}
And here is how you use it when creating your frame (inside your CalenderFrame class):
public void createFrame() {
// use this frame as reference
setJMenuBar(CalenderMenuBar.getInstance().createMenu(this));
// ... (your code goes here)
}
I want to be able to detect when all instances of JInternalFrame in a JDesktopPane are closed. I've been looking through the events fired by desktop pane and I don't see one that is applicable. I've tried adding a JInternalFrameListener to each one added to the desktop pane and listening for a closed event but that doesn't seem to work.
Here a working example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class InternalFrameDemo extends JFrame {
JDesktopPane desktop;
InternalFrameAdapter adapter;
int frameCount = 0;
public InternalFrameDemo() {
super("InternalFrameDemo");
adapter = new InternalFrameAdapter() {
public void internalFrameClosed(InternalFrameEvent e) {
frameCount--;
if (frameCount == 0) {
JOptionPane.showMessageDialog(InternalFrameDemo.this, "All internal frames closed.");
}
}
};
setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
desktop = new JDesktopPane();
createFrame();
createFrame();
createFrame();
setContentPane(desktop);
}
protected void createFrame() {
JInternalFrame frame = new JInternalFrame("title", true, true);
frame.setSize(300,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
frameCount++;
frame.addInternalFrameListener(adapter);
desktop.add(frame);
}
private static void createAndShowGUI() {
InternalFrameDemo frame = new InternalFrameDemo();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (UnsupportedLookAndFeelException e) {
// handle exception
}
catch (ClassNotFoundException e) {
// handle exception
}
catch (InstantiationException e) {
// handle exception
}
catch (IllegalAccessException e) {
// handle exception
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
You basically add a listener on each internal frame and keep track of opened and closed frames (with an int variable).
In my application, in a JDesktopPane I have added few JInternalFrames. Activation and deactivation of JInternalFrames happen normally, until one of the JInternalFrame is maximized. After that, activating an internalframe programmatically, fires internalFrameActivated, internalFrameDeactivated events multiple times. Why it is called many times? This I have observed in WindowsLookAndFeel only
public class IFTest {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(new WindowsLookAndFeel());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
JFrame frame = new JFrame();
JDesktopPane pane = new JDesktopPane();
JInternalFrame if1 = new JInternalFrame("IF1");
JInternalFrame if2 = new JInternalFrame("IF2");
if1.setTitle("IF1");
if2.setTitle("IF2");
pane.add(if1);
pane.add(if2);
frame.getContentPane().add(pane);
frame.setSize(500, 500);
frame.setVisible(true);
if1.setMaximizable(true);
if1.setSize(400, 400);
showInternalFrame(if1);
if1.addInternalFrameListener(new MyInternalFrameListener("IF1"));
if2.setMaximizable(true);
if2.setSize(300, 300);
if2.setVisible(true);
showInternalFrame(if2);
if2.addInternalFrameListener(new MyInternalFrameListener("IF2"));
System.out.println("------------------------------");
try {
if1.setMaximum(true);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
System.out.println("--------------------------------");
showInternalFrame(if2);
}
static class MyInternalFrameListener extends InternalFrameAdapter {
String name;
public MyInternalFrameListener(String name) {
this.name = name;
}
#Override
public void internalFrameActivated(InternalFrameEvent e) {
System.out.println(name + " activated");
}
#Override
public void internalFrameIconified(InternalFrameEvent e) {
System.out.println(name + " iconfied");
}
#Override
public void internalFrameDeactivated(InternalFrameEvent e) {
System.out.println(name + " deactivated");
}
#Override
public void internalFrameDeiconified(InternalFrameEvent e) {
System.out.println(name + " deiconfied");
}
}
public static void showInternalFrame(JInternalFrame intf) {
try {
if (intf.isIcon())
intf.setIcon(false);
intf.setVisible(true);
intf.moveToFront();
intf.setSelected(true);
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
}
}
Why it is called many times?
I would guess that it doesn't like to have multiple frames maximized at one time. In a normal GUI you would have to restore the currently maximized frame before you could click on another frame to maximizing it.
Your code is:
if1.setMaximum(true);
showInternalFrame(if2);
I noticed that after executing this code, if2 is maximized even though you did not explicitly ask for it to be maximized. So I'm guessing that somewhere in the code to select a frame it realizes that the current frame is maximized so there is a bunch of code that is executing that restores/deactivates the frames a couple of time until if1 is restored and if2 is selected and maximized. The code is obviously generating a bunch of events as it does this.
On the other hand if you have code like:
if1.setMaximum(true);
if1.setMaximum(false);
showInternalFrame(if2);
then you get the events as expected.
So maybe as a solution to your problem you can add code like the following in your showInternalFrame() method:
JinternalFrame active = intf.getDesktopPane().getSelectedFrame();
if (active.isMaximized())
active.setMaximum(false);
ints.setSelected(true);
My image was displaying properly before I had a JButton on top of it. Now that I have added a JButton to my code, my image does not display. In the ActionPerformed method I am telling the button to setVisbible(false). When I click the button, it disapears and all that is behind it is the background.
public class Main extends JFrame implements ActionListener {
public static void main(String[] args) {
Main main = new Main();
}
ImageIcon GIF = new ImageIcon("src/Zombie Steve gif.gif");
JButton button = new JButton("Click me!");
JLabel Label = new JLabel(GIF);
public Main() {
button.addActionListener(this);
Label.setHorizontalAlignment(0);
JFrame Frame = new JFrame("zombieSteveGIF");
Frame.setSize(650, 650);
Frame.setVisible(true);
Frame.add(Label);
Frame.add(button);
Frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
while (true) {
Frame.getContentPane().setBackground(Color.BLUE);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame.getContentPane().setBackground(Color.GREEN);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame.getContentPane().setBackground(Color.RED);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void actionPerformed(ActionEvent e) {
button.setVisible(false);
}
}
Your problem is that you have a BorderLayout (the default for JFrames), and you are adding two components in the same position. The default is BorderLayout.CENTER, and by adding two components with just the default constraints, the first one is removed and the second put in its place.
As for fixing your problem, what do you want to achieve? If you want the components to show on top of one another, you can use the OverlayLayout. If you don't want this, try some other layout manager.