I have a decorated JFrame. I need to make close button and minimize button. What should I do?
Here is my code snippet:
public Startup()
{
setTitle("STARTUP");
setSize(800,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUndecorated(true);
setLocationRelativeTo(null);
setVisible(true);
}
Your approach is very unique and will look quite good. There are many ways to solve your problem. Now, as per your request, you want a CLOSE and a MINIMIZE button. Let us make the following Actions.
private final Action exitAction = new AbstractAction("Exit")
{
#Override
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
};
private final Action minimizeAction = new AbstractAction("Minimize")
{
#Override
public void actionPerformed(ActionEvent e)
{
setState(JFrame.ICONIFIED);
}
};
Now, let us apply the above actions to JButtons:
JButton closeButton = new JButton(exitAction);
JButton miniButton = new JButton(minimizeAction);
There you have it. Now, all you need to do is add your buttons to your JFrame.
Note For Eclipse Users
this code will come in your minimize button when You click On minimize button in Eclipse.
YourFrameName is the Frame name you had set or it is set by default, use that frame name here:
YourFrameName.setState(YourFrameName.ICONIFIED);
Related
I'm curious how can I use a dialog designer that is built into IntelliJ IDEA since I find it an option with big potential but I don't really know how to use it.
Let's consider a desktop program with two classes created using designer: MainWindow and MainDialog. Let's assume that MainWindow class already has all fields, components etc. required for a simple form to be displayed. Then in the MainWindow class we have:
JLabel label = new JLabel("This is default text");
JButton showDialog = new JButton("Show dialog");
showDialog.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
MainDialog dialog = new MainDialog ();
dialog.pack();
dialog.setVisible(true);
}
});
which makes the dialog visible. The MainDialog class designed by default by designer looks like this:
public class MainDialog extends JDialog {
private JPanel contentPane;
private JButton buttonOK;
private JButton buttonCancel;
public MainDialog() {
setContentPane(contentPane);
setModal(true);
getRootPane().setDefaultButton(buttonOK);
buttonOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onOK();
}
});
buttonCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
});
// call onCancel() when cross is clicked
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
onCancel();
}
});
// call onCancel() on ESCAPE
contentPane.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
private void onOK() {
// add your code here
dispose();
}
private void onCancel() {
// add your code here if necessary
dispose();
}
}
Now let's also assume that in the dialog class I have a text field:
JTextField textField = new JTextField();
that I am getting a text to be displayed by label in the MainWindow class from.
Since I have an onOK() function created by default I'd like it to update a label in MainWindow class with text typed in text field in MainDialog class.
The problem is: how can I perform an action on another class's field using this pattern without writing in MainDialog a line MainWindow window = new MainWindow or making label static? Is it possible? I know that this can be done much simpler but this is also an easy example and I'd like to perform much more complex operations using this structure.
Yes, it's possible.
First option: since the dialog is modal, the code opening the modal in the main window will be blocked until the dialog is closed. So you could just do something like this in the modal:
public String getEnteredText() {
return textField.getText();
}
and in the main window:
dialog.setVisible(true);
myLabel.setText(dialog.getEnteredText());
Or (but I would use the first option), you can pass the main window, or any other callback, to the dialog. For example:
MainDialog dialog = new MainDialog(this);
And in the dialog:
private void onOK() {
mainWindow.setLabelText(textField.getText());
dispose();
}
My recommendation is to avoid UI designers. Especially if you're not able yet to write the code that they generate by yourself, and you don't have a deep understanding of how Swing works.
I understand how to create a button and it's application in Java. Would anyone be able to show me the code to be able to make the button in the code below be able to print something as simple as hello world in the terminal. I am using bluej if that is of any matter. I am very sorry I am a beginner coder.
JButton button = new JButton();
button.setActionListener(e -> System.out.println("Clicked"));
This uses a lambda expression. Inside it, you can add as much code as you like, but add it between {} if it's more than a line.
More on buttons here
You need a listener for your button.
JButton button= new JButton("Button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Hello World");
}
});
the button will 'listen' for the action and preform whatever task you define for it.
ActionListener is what you are looking for. There is a very nice guide on Oracle's website. You should look into this tutorial and understand different ways of creating ActionListeners. I will give you a simple example which doesn't involve Anonymous Classes because I am not sure of how much you know about them.
public class Frame extends JFrame implements ActionListener {
public Frame() {
super("Test"); // calling the superclass
setLayout(new FlowLayout()); // creating a layout for the frame
setDefaultCloseOperation(EXIT_ON_CLOSE);
// create the button
JButton jbTest = new JButton("Click me!");
/* 'this' refers to the instance of the class
because your class implements ActionListener
and you defined what to do in case a button gets pressed (see actionPerformed)
you can add it to the button
*/
jbTest.addActionListener(this);
add(jbTest);
pack();
}
// When a component gets clicked, do the following
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Hello!");
}
}
In my program I have a main JFrame that holds a button. When this button is clicked a new JFrame appears in which I can change some information. Whenever I finish editing I press a save button on the new JFrame which saves the changes and disposes the JFrame. Now when this is done, I'd like to perform an action in the main JFrame as well, but only if something changed. If I open the new JFrame and just close it again without using the save button, I don't want to do anything in the main frame.
I've tried searching the web for a solution, but just don't seem to be anything useful out there..
An example of the code I've got so far:
Main Frame...
public class MainFrame extends JFrame
{
public MainFrame()
{
super("Main Frame");
JButton details = new JButton("Add Detail");
add(details);
details.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
new DetailFrame().setVisible(true);
}
});
}
}
Detail Frame...
public class DetailFrame extends JFrame
{
public DetailFrame()
{
super("Detail Frame");
JButton save = new JButton("Save");
add(save);
save.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
// Save whatever content
dispose();
}
});
}
}
So when I click the "Save" button on the Detail Frame, I want to do something in the Main Frame, whereas when the "x" is clicked on the Detail Frame, I don't want to do anything..
Hope someone is able to help me, and sorry for my english..
You can pass a MainFrame handle to the DetailFrame constructor. Then, on clicking the Save button, the DetailFrame would call a function in MainFrame and pass the changes to it.
Another way is to create a public boolean variable in DetailFrame and set it to true when the Save button is clicked. This way MainFrame will know whether the DetailFrame was closed or Save'd.
EDIT: Some more ideas:
Use JDialog instead of JFrame. JDialog.setVisible is modal, i.e. it will block the calling function until the dialog is closed; this way you can process the results of the dialog in the same "Details" button listener.
To access the dialog after it is called, store the dialog in a separate variable. First construct the dialog, then show it, and then process the result by analyzing its variables.
Store the results of editing in other public variables of DetailFrame (or let's call it DetailDialog). This should happen only when the "Save" button is clicked. This may even allow to go without the boolean variable (depends on the types of values you are editing).
DetailDialog dlg = new DetailDialog();
dlg.setVisible(true);
if(dlg.approvedResult != null) {
// process the result...
}
EDIT: Sorry, JDialog is not modal by default. Need to call a special super constructor to make it modal.
Also, here you will have to pass the reference to MainFrame to the dialog constructor, but you still can declare it as a simple JFrame and avoid unnecessary dependencies.
To get the reference to the enclosing MainFrame from within the anonymous ActionListener, use MainFrame.this.
To be able to change the button text after it was created, you will have to store the button in a member variable.
Main Frame...
public class MainFrame extends JFrame
{
private JButton details = new JButton("Add Detail");
public MainFrame()
{
super("Main Frame");
getContentPane().add(details);
details.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
DetailDialog dlg = new DetailDialog(MainFrame.this);
dlg.setVisible(true);
if(dlg.approved){
details.setText("Edit Detail");
}
}
});
}
}
Detail Dialog... (not Frame)
public class DetailDialog extends JDialog
{
public boolean approved = false;
public DetailDialog(JFrame parent)
{
super(parent,"Detail Dialog",true); // modal dialog parented to the calling frame
JButton save = new JButton("Save");
getContentPane().add(save);
save.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
// Save whatever content
approved = true;
dispose();
}
});
}
}
Create the detail frame in the main frame, and add a windowlistener to it, using the windowadapter class. Implement the windowclosing event by checking for changes, handle those, and then dispose the detail frame. This is all done in the mainframe.
The detail frame should have do nothing on close set to prevent the detail frame being disposed before you recorded the changes.
You may wish to implement checking for changes in the detailframe as a method returning a class holding the interesting data. That way your windowlistener can be small an to the point.
Forget the 2nd JFrame. use a modal dialog instead. It will block input until dismissed. Once dismissed, the only thing to do is decide whether to update the original data. JOptionPane has some inbuilt functionality that makes that easy. If the user presses Cancel or the esc key, the showInputDialog() method will return null as the result.
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
class EditInfo {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
final JFrame f = new JFrame("Uneditable");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p = new JPanel(new BorderLayout(10,10));
final JTextField tf = new JTextField("Hello World!", 20);
tf.setEnabled(false);
p.add(tf, BorderLayout.CENTER);
JButton edit = new JButton("Edit");
edit.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent ae) {
String result = JOptionPane.showInputDialog(
f,
"Edit text",
tf.getText());
if (result!=null) {
tf.setText(result);
}
}
} );
p.add(edit, BorderLayout.EAST);
p.setBorder(new EmptyBorder(10,10,10,10));
f.setContentPane(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
If it is necessary to edit a number of fields all at once in the JOptionPane, use a JPanel to contain them all, and put them in a showMessageDialog() call. Check the integer based return result to determine if the user OK'd the changes.
I have a simple Java Swing GUI Form with a browse button. The browse button creates a new JFileChooser when it's clicked.
However, if you click browse immediately after the window opens, the file chooser window seems to loose focus, showing the parent window behind it, but it refuses to repaint itself. I have to drag it off screen and back on again to get it to return to normal.
I've tried to reduce my code to the simplest version that still has the problem. (It just makes a very large browse button.
public class FormTest extends JFrame
{
private final int width = 490;
private final int height = 400;
private JPanel outerPanel;
private static FormTest myTest;
public static void main(String[] args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch( Exception e )
{
e.printStackTrace();
}
myTest = new FormTest();
myTest.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
myTest.setResizable(false);
myTest.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
closeWindow();
}
});
myTest.setVisible(true);
}
public FormTest()
{
super("Convert Ratings");
this.setSize(width, height);
initComponents();
}
private void initComponents()
{
outerPanel = new JPanel();
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.Y_AXIS));
outerPanel.add(Box.createRigidArea(new Dimension(0, 5)));
JButton myButton = new JButton("browse");
myButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JFileChooser fileChooser = new JFileChooser();
fileChooser.showOpenDialog(myTest);
}
});
outerPanel.add(myButton);
this.add(outerPanel);
}
private static void closeWindow()
{
int result = JOptionPane.showConfirmDialog(myTest, "Are you sure you want to close the application?",
"Question", JOptionPane.YES_NO_OPTION);
if( result == JOptionPane.YES_OPTION )
{
System.exit(0);
}
}
}
In this example, the browse button must be clicked immediately after the window opens and the bug will show itself after about 10 seconds.
Any help or suggestions would be much appreciated.
Thanks,
B.J.
Since your question has changed I'll add another answer. It looks like you're looking to use a CardLayout.
The unresponsiveness of your application is probably caused by some incorrect logic with repainting/hiding/unhiding panels.
Here is Oracle's tutorial on using it
http://download.oracle.com/javase/tutorial/uiswing/layout/card.html
New Addition:
I'm currently on a mac and I can't see the issue, I'll try it again when I'm at a PC later today.
Original Post:
Sounds like a event dispatch thread issue. Make sure you are doing anything that manipulates the GUI in the event dispatch thread.
http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
Any long running task should use another thread or swing worker to perform it's function, otherwise it will cause things to stop responding/lock up/etc.
I have created a swings application and there is a "Start" button on the GUI. I want that whenever I clicked on that "Start" button, the start button should be disabled and the "Stop" button be enabled.
For that I have written the following code in the "ActionPeformed(...)" method of the "Start" button
startButton.setEnabled(false);
stopButton.setEnabled(true);
But the above code is not creating the desired affect on the GUI.
Is the above code correct for what I want to do?
It's not working with "repaint()" too.
Edit:
The code is very long so I can't paste all the code. I can tell, though, more about the code.
In the "ActionPeformed" method of "start" button, after calling the above two statements, I am executing a "SwingWorker" thread.
Is this thread creating any problem?
For that I have written the following code in the "ActionPeformed(...)" method of the "Start" button
You need that code to be in the actionPerformed(...) of the ActionListener registered with the Start button, not for the Start button itself.
You can add a simple ActionListener like this:
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
startButton.setEnabled(false);
stopButton.setEnabled(true);
}
}
);
note that your startButton above will need to be final in the above example if you want to create the anonymous listener in local scope.
The code is very long so I can't paste
all the code.
There could be any number of reasons why your code doesn't work. Maybe you declared the button variables twice so you aren't actually changing enabling/disabling the button like you think you are. Maybe you are blocking the EDT.
You need to create a SSCCE to post on the forum.
So its up to you to isolate the problem. Start with a simple frame thas two buttons and see if your code works. Once you get that working, then try starting a Thread that simply sleeps for 10 seconds to see if it still works.
Learn how the basice work first before writing a 200 line program.
Learn how to do some basic debugging, we are not mind readers. We can't guess what silly mistake you are doing based on your verbal description of the problem.
This works.
public class TestButton {
public TestButton() {
JFrame f = new JFrame();
f.setSize(new Dimension(200,200));
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
final JButton stop = new JButton("Stop");
final JButton start = new JButton("Start");
p.add(start);
p.add(stop);
f.getContentPane().add(p);
stop.setEnabled(false);
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
start.setEnabled(true);
stop.setEnabled(false);
}
});
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
start.setEnabled(false);
stop.setEnabled(true);
}
});
f.setVisible(true);
}
/**
* #param args
*/
public static void main(String[] args) {
new TestButton();
}
}