Java Swing GUI closing randomly - java

My problem is quite weird: even if I create a JFrame with literally nothing in it, so it should just display a white window, but it crashes after doing anything with it. For example, when I resize the window, the new, resized area will be black in most cases (or sometimes be the right color I really don't know why) and it will either just close or display "Not responding" and then close after a few seconds.
GUI class:
public class GUI extends JFrame {
private static JFrame frame;
public GUI() {
frame = new JFrame();
frame.setTitle("test");
frame.getContentPane().setLayout(new FlowLayout());
frame.pack();
frame.setVisible(true);
}
}
Main class:
public class Main {
public static void main(String[] args) {
GUI gui = new GUI();
}
}
And here's an image exactly showing the behavior:
Why does it behave like this? It's most definitely not because of the code, I think. It must be something else. I tried reinstalling Java, didn't help out. Switched from SDK 13 to 1.8.0_171, nothing. Older programs using Swing also suddenly don't work anymore and behave the same. Any ideas?

Always start your GUI from the event dispatching thread to avoid unwanted behavior.
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI();
}
});
}
See the javadoc: invokeLater

Try this (width 400, height 300):
public class GUI extends JFrame {
private static JFrame frame;
public GUI() {
frame = new JFrame();
frame.setTitle("test");
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)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
frame.pack();
frame.setVisible(true);
}
}

Related

Java Netbeans: How to open the JPanel from another class?

I have a main.java file which I like to use to call the GUI made in JPanel.
It's my first NetBeans experience though, so be gentle :-) ...
It fails to compile; the error i get is :Erroneous sym type: main.GUI.GUI (which makes sense as it is interpreted).
But now: HOW DO I FIX IT??
I've tried GUI.GUI(); as well, but without positive results..
(I'm used to programming C++, but since import is not a true option in java (or is it?).
My main.java:
package main;
public class Main {
public static void main(String[] args) {
GUI obj = new GUI();
obj.GUI();
}
}
My GUI.java file:
package main;
public class GUI extends javax.swing.JPanel {
public GUI() {
initComponents();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}
}
If I understand your question correctly you want to display the GUI from your Main class. One thing to keep in mind is that a JPanel itself cannot be displayed. It must be added to a JFrame before it shows. Try something like:
package main;
public class Main {
public static void main(String[] args) {
GUI obj = new GUI(); // creates your panel
JFrame frame = new JFrame("some title"); // creates the frame
frame.add(obj);
frame.setSize(200,300);
frame.setVisible(true);
}
}
GUI obj = new GUI();
it created new object of GUI. So, the constructor is operated already. The constructor method is special method, that plays when new object is created from the class.

components in Jdialog not shown

My application is created using Netbeans IDE (8.0.2).
I have created a JFrame which contains a JTable bound to a Database (using JPA).
I have added a "Refresh" button which is used to "refresh" the JTable data directly from the database.
I want a "Please wait" message to be displayed while data is being fetched.
For this I implemented a JDialog_PleaseWait class which extends JDialog.
For some strange reason, although the JDialog is shown the jLabel it includes does not show up...
The JDialog_PleaseWait class is :
public class JDialog_PleaseWait extends javax.swing.JDialog {
//constructor for PleaseWait jDialogs
public JDialog_PleaseWait(String messageToDisplay){
initComponents();
this.jLabel_WaitMessage.setText(messageToDisplay);
}
/**
* 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">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel_WaitMessage = new javax.swing.JLabel();
setTitle("Please wait...");
setAlwaysOnTop(true);
setBackground(new java.awt.Color(227, 248, 115));
setModalityType(java.awt.Dialog.ModalityType.MODELESS);
setResizable(false);
setType(java.awt.Window.Type.POPUP);
jLabel_WaitMessage.setBackground(new java.awt.Color(242, 253, 153));
jLabel_WaitMessage.setText("WaitMessage");
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()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel_WaitMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 271, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel_WaitMessage)
);
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel_WaitMessage;
// End of variables declaration//GEN-END:variables
}
The refresh JButton calls a method named "reload" which initially it must display the jDialog and perform the rest of its tasks afterwards.
More specifically :
public void reload(){
jTable_Activities.setEnabled(false); // freezes the JTable
JDialog_PleaseWait pleaseWaitDialog = new JDialog_PleaseWait("Communicating with database server...."); // create a new PleaseWait JDialog
pleaseWaitDialog.pack();
pleaseWaitDialog.setLocationRelativeTo(this); //relative to this frame
pleaseWaitDialog.setVisible(true); //display the JDialog
.... ....
// runs a DB query and updates a JTable
.... ....
So, for some reason the JDialog window pops up but the jLabel is not shown...
I(think I) have done the (exact?) same thing with other JDialogs which work fine but for some strange reason this JDialog does not work properly...
Any hint?
Your likely problem is that you're fetching your data on the Swing event thread (I don't see any code above where you use Thread/Runnable/SwingWorker or the like, and hence my assumption), and that this is tying up the event thread and preventing it from doing its chores -- including drawing the label to the JDialog. The solution: do the data fetching in a background thread such as by using a SwingWorker.
Here's an example that demonstrates what I mean. The code creates two JButtons, one which displays a JDialog for 2 seconds with a Thread.sleep(...) running on the Swing event thread during that 2 seconds, the other with the Thread.sleep(...) running in a background thread. Compile and run the code to see what happens.
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class PleaseWaitDialogTest extends JPanel {
protected static final long SLEEP_TIME = 2000L;
public PleaseWaitDialogTest() {
add(new JButton(new ShowWaitDialog("Without Thread", KeyEvent.VK_O, false)));
add(new JButton(new ShowWaitDialog("With BG Thread", KeyEvent.VK_W, true)));
}
private class ShowWaitDialog extends AbstractAction {
private boolean useBackgroundThread;
private JDialog dialog;
public ShowWaitDialog(String name, int mnemonic,
boolean useBackgroundThread) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.useBackgroundThread = useBackgroundThread;
}
#Override
public void actionPerformed(ActionEvent e) {
// create dialog in a lazy way
if (dialog == null) {
Window ancestorWindow = SwingUtilities
.getWindowAncestor(PleaseWaitDialogTest.this);
String title = "Dialog: " + getValue(NAME);
dialog = new JDialog(ancestorWindow, title,
ModalityType.MODELESS);
dialog.getContentPane().setLayout(new GridBagLayout());
dialog.add(new JLabel("Please Wait"));
dialog.setPreferredSize(new Dimension(250, 150));
dialog.pack();
dialog.setLocationByPlatform(true);
}
dialog.setVisible(true);
// since the dialog is non-modal, this code will run immediately after
// the dialog has been set visible
CloseRunnable closeRunnable = new CloseRunnable(dialog, SLEEP_TIME);
if (useBackgroundThread) {
// run the Runnable in a background thread
new Thread(closeRunnable).start();
} else {
// run the Runnable directly on the Swing event thread
closeRunnable.run();
}
}
}
private class CloseRunnable implements Runnable {
protected JDialog dialog;
private long sleepTime;
public CloseRunnable(JDialog dialog, long sleepTime) {
this.dialog = dialog;
this.sleepTime = sleepTime;
}
#Override
public void run() {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
// the dialog *must* be closed on the Swing event thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (dialog != null) {
dialog.setVisible(false);
}
}
});
}
}
private static void createAndShowGui() {
PleaseWaitDialogTest mainPanel = new PleaseWaitDialogTest();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

setUndecorated(true) messing with toFront()

I have these two JFrames that work just fine when setUndecorated is set to false, but it doesn't work consistently when it's set to true;
frame = new JFrame("Name of the frame"); // main frame
frame.setAlwaysOnTop(false);
frame.setSize(width, height);
frame.add(canvas);
frame.setUndecorated(true);
frame.setVisible(true);
menu = new MenuUI(); // this is also a undecorated JFrame
menu is called by a mouse event, but it sometimes shows up in the front and sometimes it shows in the back of the main frame...
public static void checkMove(int action, MouseEvent e) {
int x = e.getX();
if(x == 0){
menu.setVisible(true);
menu.toFront();
}else{
menu.setVisible(false);
}
I've tried to do frame.toBack(); but it sends the frame behind everything else as well...
How can I bring undecorated JFrame in front of another undecorated JFrame and make it consistent?
EDIT: the menu frame disappears on mouse event
contentPane.addMouseListener(new MouseAdapter() {
#Override
public void mouseExited(MouseEvent e) {
setVisible(false);
}
});
EDIT2: after mKorbel's answer, I've tried to create a JDialog, but I get the same result as with JFrame. How can I set the parent if I extend a JDialog?
package menu;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JDialog;
import openGL.main.openGLMain;
#SuppressWarnings("serial")
public class menuTest extends JDialog {
public menuTest() {
setUndecorated(true);
setBounds(0, 0, 250, frame.getHeight());
GroupLayout groupLayout = new GroupLayout(getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGap(0, 450, Short.MAX_VALUE)
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGap(0, 700, Short.MAX_VALUE)
);
getContentPane().setLayout(groupLayout);
getContentPane().addMouseListener(new MouseAdapter() {
#Override
public void mouseExited(MouseEvent e) {
setVisible(false);
}
});
}
}
JFrame by default never react to AlwaysOnTop or toFront correctly, isn't main functionality for primary Top-Level Container (without iconify and deiconify, but then flashing on the screen)
you have to use JDialog for this job, set for parent and modality (if needed)
JFrame by default never react to AlwaysOnTop or toFront correctly, isn't main functionality for primary Top-Level Container (without iconify and deiconify, but then flashing on the screen)
you have to use JDialog for this job, set for parent and modality (if needed)
exactly and also you can use JinternalFrame that makes you have some children frame in your main Jframe and you can iconify and deiconify or close which is don't needed and also make them resizable if you need.
and if you want make them in front or back to others,you can make it easily by Drag&Drop that Frame Children!

Massive space between components

Please have a look at the following code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridLayoutTest2
{
private final JDialog msgDisplayer;
public GridLayoutTest2()
{
JLabel maleLabel = new JLabel("Male",JLabel.CENTER);
maleLabel.setBorder(BorderFactory.createEmptyBorder());
JLabel femaleLabel = new JLabel("Female",JLabel.CENTER);
femaleLabel.setBorder(BorderFactory.createEmptyBorder());
JLabel fmaleIcon = new JLabel();
fmaleIcon.setIcon(new ImageIcon(getClass().getResource("/images/TESTING-Image.gif")));
fmaleIcon.setBorder(BorderFactory.createEmptyBorder());
JLabel maleIcon = new JLabel();
maleIcon.setIcon(new ImageIcon(getClass().getResource("/images/TESTING-Image.gif")));
maleIcon.setBorder(BorderFactory.createEmptyBorder());
msgDisplayer = new JDialog();
msgDisplayer.setLayout(new GridLayout(4,1,1,1));
msgDisplayer.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
msgDisplayer.setTitle("Body Fat Percentage Classification");
msgDisplayer.add(femaleLabel);
msgDisplayer.add(fmaleIcon);
msgDisplayer.add(maleLabel);
msgDisplayer.add(maleIcon);
msgDisplayer.pack();
msgDisplayer.setVisible(true);
msgDisplayer.setLocationRelativeTo(null);
}
public static void main(String[]args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new GridLayoutTest2();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
This code contains a HUGE gap (space) between the labels and images screenshot attached). I do not want to have this space between labels and images. How can I eliminate it? I know I can go with the GridBagLayout to do it, but, is there any way in GridLayout? Please help!
GridLayout allocates an equals amount of space for all components based on the largest component in the container. If you don't wish to use a complex layout manager such as GridBagLayout, you could use BoxLayout, which uses the component's preferred sizes. A BoxLayout with Y_AXIS alignment would be suitable here.
Example
Thats not the gap space, its real size of JLabel's (maleLabel, fmaleLabel). Size of image determines size of parent JLabel and in GridLayout, all components will take size of largest component. Gap between components is 1 as you defined when setting layout. So solution of your problem lays in finding suitable layout manager.
Reimeus gave you an example of GridBagLayout and BoxLayout, and I would like to recommend you MiGLayout which is quite easy to use.
Its the Layout what matters!!
Here I have done a short EG with my GUI builder to show the adjustment of white space(or the size of JLabel):
More white space:
Code:
public class udyfash extends javax.swing.JFrame {
public udyfash() {
initComponents();
}
#SuppressWarnings("unchecked")
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images.jpg"))); // NOI18N
jLabel1.setText("yooo!!");
jLabel1.setBorder(javax.swing.BorderFactory.createCompoundBorder(null, javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 405, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(44, 44, 44)
.addComponent(jLabel1)
.addContainerGap(39, Short.MAX_VALUE))
);
pack();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new udyfash().setVisible(true);
}
});
}
private javax.swing.JLabel jLabel1;
}
We say GridBag is complex,but use the Layout Manager you are ok with.

How can I minimize/iconify a JWindow in Java?

My app has a JWindow that needs to be minimized when the custom minimizer button clicked.
Please reply if anyone knows how to minimize a JWindow. I have searched a lot but couldn't find any suitable method to minimize.
I know how to minimize a JFrame. So please don't bother answering regarding JFrame.
Thanks.
I know you don't want to hear this, but the terrible truth is that there is no big difference between undecorated jframes (with setstate methods) and jwindows... :)
JFrame f = new JFrame("Frame");
f.setUndecorated(true);
Due to the fact that a JWindow is not decorated with any control icons, no setState method is provided. One workaround is to allow your custom minimizer button to set the window visible as required:
public class JWindowTest extends JFrame {
JWindow window = new JWindow();
JButton maxMinButton = new JButton("Minimize Window");
public JWindowTest() {
setSize(300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
maxMinButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (window.isVisible()) {
maxMinButton.setText("Restore Window");
} else {
maxMinButton.setText("Minimize Window");
}
window.setVisible(!window.isVisible());
}
});
add(maxMinButton);
window.setBounds(30, 30, 300, 220);
window.setLocationRelativeTo(this);
window.add(new JLabel("Test JWindow", JLabel.CENTER));
window.setVisible(true);
}
public static void main(String[] args) {
new JWindowTest().setVisible(true);
}
}

Categories