Java, Swing and Xubuntu, JFrames not correct - java

I'm completely new to Linux and have been trying to get my (Windows built) Java Swing projects to work correctly on XUbuntu on a separate machine from executable jar files I built.
I've reduced the problem to a minimum amount of code
import java.awt.Dimension;
import javax.swing.*;
public class JFrameTest extends JFrame {
public JFrameTest(String title) {
super(title);
JLabel lab = new JLabel("Label");
this.getContentPane().add(lab);
this.setMinimumSize(new Dimension(200, 200));
this.pack();
this.setVisible(true);
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JFrameTest frame = new JFrameTest("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
On Windows I see:
In Xubuntu I just see a grey box and the label, not the Title or close icons etc. I also have to kill (-9) the jvm after I've ctrl zedded from the command line. I launched it with java -jar filename.jar
My Linux machine is running Xubuntu 11. I've installed the sun Java 6_24 JRE. I Googled for this and found something similar relating to Compziz(?) but this was allegedly fixed a while back. I'm a bit stuck now. I have got one Swing app that works OK in that it responds to buttons OK but still doesn't show the Title etc. Any help would be much appreciated.

I don't use Xubuntu, but the general rule is that any code that updates a GUI should be executed on the Event Dispatch Thread. See the section from the Swing tutorial on Concurrency.
The examples from the Swing tutorial all use a format like this:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
add( new JLabel("Label") );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SSCCE() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}

Suggestion: Start the GUI on the EDT. Vis.
import java.awt.Dimension;
import javax.swing.*;
public class JFrameTest extends JFrame {
public JFrameTest(String title) {
super(title);
JLabel lab = new JLabel("Label");
this.getContentPane().add(lab);
this.setMinimumSize(new Dimension(200, 200));
this.pack();
this.setVisible(true);
}
public static void main(String args[]) {
// Costruct & show the GUI on the EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JFrameTest frame = new JFrameTest("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
}
For more information see Concurrency in Swing.

Related

Button that opens a new JFrame

I'm writing a program where I am supposed to have a title screen for a game, where you can click a 'play' button that opens a different window and simultaneously closes the other one. What I am attempting to do is utilize an ActionListener for a button that makes the current window invisible while simultaneously making a different window visible. I am having a hard time getting this to work and am encountering a lot of syntax and logical errors. I'm quite certain there is a better way to do this, so any pointers will be greatly appreciated. I am using swing. Disclaimer: beginner java level programmer lol :p
My first class includes this (does not include my imports):
public static void main(String[] args) {
//Creating the Frame
MyFrame menuFrame = new MyFrame();
// (here i have code for the frame in my actual program)
}
static class MyFrame extends JFrame {
MyFrame () {
this.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(new JLabel(new ImageIcon("logo.png")));
this.pack();
this.setVisible(true);
new EightOff.returnHomeListener (this);
}
}
}
My other class that has the other frame being opened includes the following button and action listener where I am trying to reference my frame from GameMenu:
public class EightOff
{
private static JButton returnHome = new JButton("Return to Game Menu");
public static class returnHomeListener implements ActionListener {
public returnHomeListener(GameMenu.MyFrame myFrame) {
}
#Override
public void actionPerformed(ActionEvent e)
{
returnHomeListener (JFrame visibleFrame) {
visibleFrame.toSetVisible (true);
}
}
}
}
You should start by having a look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listener
The ActionListener should be registered to the button, so if can be notified when some action occurs, for example...
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JButton button = new JButton("Click me");
button.addActionListener(new TestActionListener());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "I'd prfefer if you did't do that");
}
}
}
In order to make changes to a object, you first need a reference to that object. This is pretty basic, Java 101 kind of stuff and you should have a look at Passing Information to a Method or a Constructor for more details.
You should also have a read of the JavaDocs for JFrame to get a better understanding of what properties and functionality the class provides.
Having a look at How to Make Frames also wouldn't hurt.
I'd recommend having a look at How to use CardLayout instead of trying to hide/show windows, you'll have a better user experience generally.

How to make JFrame active (focused)?

When dialog window displayed it does not focused if other window is active (i.e. you need to focus it by mouse pointer to be able to deal with it). How can I make a focus to displayed dialog?
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class GuiTest {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "test info", "test header",
JOptionPane.INFORMATION_MESSAGE);
//frame.toFront();
//frame.requestFocus();
frame.dispose(); // When a frame is disposed, the exit action will be
// called.
}
}
JOptionPane.showMessageDialog stops the EDT (Event Dispatching Thread) until the dialog is closed.
You could instead use another JFrame instead of a JOptionPane
package util;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GuiTest {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GuiTest window = new GuiTest();
window.frame.setVisible(true);
Dialog d = new Dialog();
d.show();
window.frame.requestFocus();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public GuiTest() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class Dialog extends JFrame {
private JFrame frame;
public void show() {
if (frame == null) {
frame = new JFrame();
frame.setTitle("Dialog");
frame.setBounds(100, 100, 450, 300);
frame.add(new JTextField("Hello"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
frame.setVisible(true);
}
}
try to run it and right after that make any other window active
Once a window loses focus you need to either:
click on the window to give it focus
Use the desktop manager to access the application. In Windows this is done by using Alt+Tab to cycle through open applications.
The problem is that only a JFrame is added to the desktop manager so if you want the ability to use Alt+Tab then you need to make the frame visible BEFORE showing the option pane.
Of course the JFrame will now be visible on the screen so you can use the setLocation(...) method with a negative value to hide the frame from the visible desktop.

Windows key + right/left arrow keys doesn't work on undecorated frame in swing

I have an undecorated ( setUndecorated(true) ) frame which doesn't behave properly when pressing windows key + right/left arrow keys.
Please refer the sample code bellow :
import javax.swing.*;
import java.awt.*;
public class TestGUI {
private static void createAndShowGUI() {
JFrame frame = new JFrame("HelloWorldSwing") {
#Override
public boolean isUndecorated() {
return super.isUndecorated();
}
};
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.setPreferredSize(new Dimension(400, 400));
frame.setUndecorated(true);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
But when I set the frame as setUndecorated(false), then it works properly. I couldn't find any java bug related to this issue. Is there a work around which I could use to get the same behavior with setUndecorated(true)?

Java - Applet to Executable Jar Wrapping

I have written a Java XML Parser as an Applet. It is looking and functioning well enough in this form.
My Question, Is if I want to run this without a browser, how Would I properly wrap it to run as an executable?
GUI.java
--------------
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GUI extends JPanel implements ActionListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
private Parser xmlEditor;
private String startTimeValue;
private String endTimeValue;
public GUI(){
init();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new GUI();
}
});
}
public void init() {
this.setXmlEditor(new Parser("C:\\Users\\Administrator\\workspace\\XMLParser\\src\\test.xml"));
add(new Label("Start Time"));
startTimeValue = xmlEditor.getStartTimeValue();
endTimeValue = xmlEditor.getEndTimeValue();
startTime = new TextField(startTimeValue);
add(new Label("End Time"));
endTime = new TextField(endTimeValue);
save = new Button("save");
save.addActionListener(this);
add(startTime);
add(endTime);
add(save);
}
public void actionPerformed(ActionEvent e)
{
System.out.println(endTime.getText());
xmlEditor.updateStartTimeValue(startTime.getText());
xmlEditor.updateEndTimeValue(endTime.getText());
System.out.println(e);
System.exit(0);
}
public Parser getXmlEditor() {
return xmlEditor;
}
public void setXmlEditor(Parser xmlEditor) {
this.xmlEditor = xmlEditor;
}
TextField startTime, endTime;
Button save;
}
While trying things with Swing and JFRame etc, I am not getting properly layout, or am opening multiple windows. Can anyone provide assistance? The second Panel Keeps replacing the First. Id like to really try to learn how to place multiple components inside an executable jar is the goal.
SwingPaintDemo.java
import java.awt.Label;
import java.awt.TextField;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
public class SwingPaintDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
Parser myParser = new Parser("C:\\Users\\Administrator\\workspace\\XMLParser\\src\\test.xml");
JPanel top = new JPanel();
top.add(new Label("Start Time"));
TextField startTimeField = new TextField(myParser.getStartTimeValue());
top.add(startTimeField);
f.getContentPane().add(top);
JPanel bottom = new JPanel();
bottom.add(new Label("End Time"));
TextField endTimeField = new TextField(myParser.getEndTimeValue());
bottom.add(endTimeField);
f.getContentPane().add(bottom);
f.pack();
}
}
JFrame uses a BorderLayout by default, where as a JPanel uses a FlowLayout
Instead of rebuilding the UI in the JFrame, simply add an instance of GUI to it, since you've already defined the functionality in a JPanel, this makes it easily reusable.
public class SwingPaintDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new GUI());
f.pack();
f.setVisible(true);
}
}
FYI: You should never reference src in any path element, src won't exist once the program is built and packaged. This is also doubly concerning for applets, as applets run in a tight security model, which prevents them from accessing the file system by default.
Instead, you should be using Class#getResource or Class#getResourceAsStream, depending on your needs.
this.setXmlEditor(new Parser(getClass().getResource("/test.xml")));
for example. You may need to change your Parser to accept either a URL and/or InputStream as well

Full screen frame issue

I have this code, which basically initializes a new JFrame and sets it full screen
public class FullScreenFrameTest extends JFrame {
public FullScreenFrameTest() {
super();
initFrame();
setVisible(true);
//full screen
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
device.setFullScreenWindow(this);
//end full screen
}
public void initFrame() {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setUndecorated(true);
setLocation(0, 0); //tried removing this, still doesn't work
setSize(screen.width, screen.height);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
new FullScreenFrameTest();
}
}
The problem is that it sometimes it does work and sometimes it doesn't, especially with Ubuntu: sometimes i see it full screen, sometimes the two bars are shown. What am i missing?
UPDATE
There is a screenshot:
Make sure to build your GUI on the event dispatch thread with invokeLater().
Update: Here's an SSCCE that seems to work consistently.
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class FullScreenFrameTest extends JFrame {
public FullScreenFrameTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setUndecorated(true);
add(new JLabel("Test", JLabel.CENTER));
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
device.setFullScreenWindow(this);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new FullScreenFrameTest();
}
});
}
}
Change
setLocation(0, 0); //tried removing this, still doesn't work
setSize(screen.width, screen.height);
To
setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
setLocationRelativeTo(null);
And call FullScreenFrameTest() constructor within SwingUtilities.invokeLater.
UPDATE
This might be due to the bug in java run time environment. Here is the bug reported http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7057287
To know more about this issue look at HERE.
UPDATE
As last tryI would suggest you to use JFrame#setAlwaysOnTop(true)

Categories

Resources