I am using JWindow in my project to display a UI that is undecorated and also doesn't appear in the task bar. But, the JWindow always seems to be on top of all other windows. I tried setting the setAlwaysOnTop to false, but it didn't seem to help.
Here's the code that can reproduce the problem :
package test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JWindow;
public class Test extends JWindow implements ActionListener {
public Test() {
setSize(300, 300);
setLocationRelativeTo(null);
setAlwaysOnTop(false);
JButton myButton = new JButton("Click Here");
myButton.addActionListener(this);
getContentPane().add(myButton);
setVisible(true);
}
public static void main(String[] args) {
new Test();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Click Here"))
JOptionPane.showMessageDialog(this, "This dialog box appears behind the JWindow!");
}
}
My OS is Linux and I'm using the Oracle JDK 6. Also, while I was testing my app on Windows, I was using JDialog for the UI and it was working fine. But, in Linux JDialog seems to appear in the task bar.
Any help as to how to solve this?
After you set the visibility of the window to True, you send it to the back like this:
setVisible(true);
toBack();
If, later, you want to bring it to the top of the stacking order, you simply call:
toFront();
More details here:
http://docs.oracle.com/javase/6/docs/api/java/awt/Window.html#toBack()
http://docs.oracle.com/javase/6/docs/api/java/awt/Window.html#toFront()
Related
I'm trying to followed java tutorials and now I am going over JFrame.
This is a information inquiry more than help question.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Login {
public static void main(String[] args){
//Creating object of LoginFrame class and setting some of its properties
LoginFrame frame = new LoginFrame();
frame.setTitle("LoginForm");
frame.setVisible(true);
frame.setBounds(10, 10, 370, 600);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
This code will cause the frame to be resized to a very small size at the top left corner regardless of the bounds I set.
A simple fix for this is to place frame.setResizable() before setting its bounds.
Does anyone know why this happens or am I doing something wrong?
I'm also on Ubuntu 20.04, maybe this matters but I haven't found an answer.
Tutorial shows above code.
The following is the code for LoginFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//Creating LoginFrame class
public class LoginFrame extends JFrame implements ActionListener {
//Creating constructor of LoginFrame() class
LoginFrame(){
}
//Overriding actionPerformed() method
#Override
public void actionPerformed(ActionEvent e){
}
}
Like I was saying I was only following a tutorial. This was only the beginning of the tutorial but I had the same issue when starting another very simple frame tutorial.
The following works fine for me :
import javax.swing.*;
class Scratch extends JFrame {
public Scratch() {
super();
}
public static void main(String[] args){
//Creating object of LoginFrame class and setting some of its properties
Scratch frame = new Scratch();
frame.setTitle("LoginForm");
frame.setVisible(true);
frame.setBounds(10, 10, 370, 600);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Result : I see a big rectangular window - in the shape of a smart phone screen I'd say.
setResizable(false) means you cannot resize the frame. I suspect the problem you're trying to identify lies somewhere in the LoginFrame class... no code for this was included though so hard to comment furhter.
I've created an applet game, but when I modify some of the contents, I need to (maximise or minimise) resize the window to show my modified applet.
even when I add a label, or anything, it needs resizing since I've not used the paint method.(no use of repaint).
Help me with this, how to show modified contents without resizing...
here's a sample code that have same problem.
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
public class Appl extends JApplet implements ActionListener{
Button b = new Button();
public void init()
{
setLayout(new FlowLayout());
setSize(300,300);
setVisible(true);
add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==b)
{
add(new Label("Button clicked"));
repaint();
}
}
}
If I remember correctly you just call the repaint method after the modifications of your content, then it should show up.
Repaint is always implicitly called when you resize the Applet.
Edit: Applying the validate medthod on the Japplet Container works for me in the given example. This also redraws added components, repaint just calls the paint method. try it :-)
We have built a Point of Sale system and now we require to implement it to Touch screens? Do we need to change any code in turn to allow this to work.
And we are using the Keyboard to enter values - let's say quantity - Is there a java way of popping up a key board (like android) when I focus on a JTextField?
Here is a simple example on how to implement a pop-up keyboard:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class MainFrame extends JFrame
{
private JTextField txt;
private PopUpKeyboard keyboard;
public MainFrame()
{
super("pop-up keyboard");
setDefaultCloseOperation(EXIT_ON_CLOSE);
txt = new JTextField(20);
keyboard = new PopUpKeyboard(txt);
txt.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
Point p = txt.getLocationOnScreen();
p.y += 30;
keyboard.setLocation(p);
keyboard.setVisible(true);
}
});
setLayout(new FlowLayout());
add(txt);
pack();
setLocationByPlatform(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MainFrame().setVisible(true);
}
});
}
private class PopUpKeyboard extends JDialog implements ActionListener
{
private JTextField txt;
public PopUpKeyboard(JTextField txt)
{
this.txt = txt;
setLayout(new GridLayout(3, 3));
for(int i = 1; i <= 9; i++) createButton(Integer.toString(i));
pack();
}
private void createButton(String label)
{
JButton btn = new JButton(label);
btn.addActionListener(this);
btn.setFocusPainted(false);
btn.setPreferredSize(new Dimension(100, 100));
Font font = btn.getFont();
float size = font.getSize() + 15.0f;
btn.setFont(font.deriveFont(size));
add(btn);
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
txt.setText(txt.getText() + actionCommand);
}
}
}
If you don't need multi-touch, the normal mouse drivers for use with most touch screen controllers will just have the touch-screen emulate a normal mouse where a finger touching the screen is emulated as a mouse click.
As for a virtual keyboard, there are crummy ones built into Windows and MacOSX but it would probably be best to build one into the application if you can.
If you need multi touch or have issues with specific touch screen controllers, there are a few options.
Your best bet in swing, at least on windows, seems to be this project: http://www.michaelmcguffin.com/code/JWinPointer/
JavaFX appears to have touch support, Intel has a tutorial: https://software.intel.com/en-us/articles/using-javafx-to-implement-multi-touch-with-java-on-windows-8-desktop. You might be able to get this working with swing somehow as there are methods to host Swing in JavaFX and JavaFX in Swing, you might look for other answers to accomplish interop between both.
There was project MT4J, but it seems to be defunct. It doesn't seem to work with Swing or JavaFX.
You should be able to provide your own virtual keyboard through the use of something like a JWindow and the KeyboardFocusManager
We implemented a custom Look-and-feel for our Swing application with touch support to make everything just look bigger (all buttons, checkboxes, ..., even JTree instances) so that it is easy to modify them using a finger.
Such a solution might save you the work to convert all your UI's to a touch-friendly UI.
You should change your user experience and interaction design, thus change the code. Check out Windows UX guidelines for touch - https://msdn.microsoft.com/en-us/library/windows/desktop/dn742468.aspx
I'm having issues figuring out how to open one window when another closes if the other window is initiated within a sub class. Here is the clumsy code I am trying to use, but it halts the setting visible of the sub classe's window. Perhaps due to it being within an action event or perhaps it is halting the main thread.
tutorial = new tutorialWindow();
this.setVisible(false);
tutorial.setLocationRelativeTo(null);
tutorial.setVisible(true);
tutorial.setCurrentUser(users.getCurrentUser());
while(tutorial.isOpen() == true ) {
}
this.setVisible(true);
users.updateUser(tutorial.getCurrentUser());
My thoughts were that it would just get stuck in the section of code until the other window closes and would then appear again when the tutorialWindow has a Open boolean set to false due to it breaking the while loop.
Im sure this is a matter of using correct threads, or perhaps the various notify methods but as of now I am not sure how to do that.
You could do it using WindowListener. In the following sample WindowAdapter implements WindowListener and I just override the public void windowClosed(final WindowEvent e) method, opening the second window.
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TestJFrame {
public static void main(final String args[]) {
JFrame jFrame1 = new JFrame();
jFrame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame1.add(new JLabel("First JFrame"));
jFrame1.pack();
final JFrame jFrame2 = new JFrame();
jFrame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame2.add(new JLabel("Second JFrame"));
jFrame2.pack();
jFrame1.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(final WindowEvent e) {
jFrame2.setVisible(true);
}
});
jFrame1.setVisible(true);
}
}
I just wrote this test code in my CustomUIPanel class:
public static void main(String[] args) {
final JDialog dialog = CustomUIPanel.createDialog(null,
CustomUIPanel.selectFile());
dialog.addWindowListener(new WindowAdapter() {
#Override public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
It works correctly if CustomUIPanel.main() is the program's entry point, but it makes me wonder something: what if another class called CustomUIPanel.main() for testing? Then my call to System.exit(0) is incorrect.
Is there a way to tell the Swing event dispatch thread to exit automatically if there are no top-level windows?
If not, what's the right thing for a JDialog/JFrame to do upon closing if the goal is for the program to exit when all the top level windows are closed?
You can use the setDefaultCloseOperation() method of JDialog, specifying DISPOSE_ON_CLOSE:
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
See also 12.8 Program Exit.
Addendum: Incorporating #camickr's helpful answer, this example exits when either the window is closed or the close button is pressed.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
/** #see http://stackoverflow.com/questions/5540354 */
public class DialogClose extends JDialog {
public DialogClose() {
this.setLayout(new GridLayout(0, 1));
this.add(new JLabel("Dialog close test.", JLabel.CENTER));
this.add(new JButton(new AbstractAction("Close") {
#Override
public void actionPerformed(ActionEvent e) {
DialogClose.this.setVisible(false);
DialogClose.this.dispatchEvent(new WindowEvent(
DialogClose.this, WindowEvent.WINDOW_CLOSING));
}
}));
}
private void display() {
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new DialogClose().display();
}
});
}
}
Not sure about when using a JDialog.
But when using a JFrame you should use frame.dispose(). If the frame is the last open frame then the VM will exit.
Note a dialog does not have an EXIT_ON_CLOSE option since it should not generally exit the VM.
When closing the dialog you could always get the dialogs parent frame. Then you could dispatch an event to the frame to tell it to close itself. Something like:
WindowEvent windowClosing = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
//Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowClosing);
frame.dispatchEvent(windowClosing);
Use
this.dispose();
It should work.
Well,
You could use a JFrame instead. JDialog is supposed to be used as popup of an application that runs in an JFrame to catch the users attention and to pause the main application.
If the JFrame is closed, you can call System.exit(0)
dialog has a getParent() method, which I guess, is set to null in your case here CustomUIPanel.createDialog(null,
you can use that to exit conditionally.
Here is what I would recommend : dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);