I'm trying to make to make some text appear before my applet loads so I've made a simple SSCCE(.org):
import java.awt.*;
import javax.swing.*;
public class test extends JApplet {
public void init() {
this.add(new JLabel("Button 1"));
System.out.println("Hello world...");
try {
Thread.sleep(3000);
}catch(Exception hapa) { hapa.printStackTrace(); }
}
}
If you run it, the Button 1 will appear AFTER the 3 seconds when it's suppose to appear BEFORE that... what am I doing wrong?
I think the init() method has to return before the items are rendered.
JustinKSU covered the technical part of the question.
A better strategy would be to use the image param to show a 'splash' before the applet appears. See Special Attributes of Applets for further details.
I want one for a fixed amount of time... not just the loading.
In that case, put a CardLayout in the applet. Add the 'splash' to the first card, the rest of the GUI to another. At the end of the init() create a non-repeating Swing Timer that will flip to the card with the main GUI.
E.G.
// <applet code='SplashApplet' width='400' height='400'></applet>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SplashApplet extends JApplet {
public void init() {
final CardLayout cardLayout = new CardLayout();
final JPanel gui = new JPanel(cardLayout);
JPanel splash = new JPanel();
splash.setBackground(Color.RED);
gui.add(splash, "splash");
JPanel mainGui = new JPanel();
mainGui.setBackground(Color.GREEN);
gui.add(mainGui, "main");
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
cardLayout.show(gui, "main");
}
};
Timer timer = new Timer(3000, listener);
// only needs to be done once
timer.setRepeats(false);
setContentPane(gui);
validate();
timer.start();
}
}
Related
I'm making a program that has a popup menu with two buttons, one of which should close the popup menu, but I have no idea how to do that and googling hasn't gone too well.
I've tried using popup.hide() but then the menu wouldn't come back, despite doing so when I tried just moving the popup. It also required me to put a SuppressWarning in that case and it took a few seconds for it to close at all. Is there any better way of doing it?
I'm not sure what kind of code is relevant, but here's the relevant buttons and their roles in this(I skipped all the creating the GUI parts that didn't seem relevant, everything looks good and I know that the buttons are working):
package test;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
interface CustomButton {
JButton create();
void react(JPopupMenu popup, JFrame frame);
}
class ErrandsButton implements CustomButton {
private JButton errands = new JButton("Errands");
public JButton create() {
return errands;
}
public void react(JPopupMenu popup, JFrame frame) {
errands.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
popup.show(frame, 120, 65);
}
});
}
}
class Test {
static JFrame frame = new JFrame("List");
static CustomButton errands = new ErrandsButton();
static JButton cancelTask = new JButton("Cancel");
static JPopupMenu popup = new JPopupMenu();
static void cancelTask() {
cancelTask.addActionListener(new ActionListener() {
#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e) {
popup.hide();
}
});
}
public static void main(String args[]) {
createInterface();
cancelTask();
errands.react(popup, frame);
}
static void createInterface() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
JPanel popup1 = new JPanel();
JPanel button = new JPanel();
popup1.add(cancelTask);
popup.add(popup1);
frame.add(popup);
button.add(errands.create());
frame.getContentPane().add(BorderLayout.CENTER, button);
frame.setVisible(true);
}
}
Use popup.setVisible(true) and popup.setVisible(false).
frame.add(popup); is the problem. Do not add a JPopupMenu to a Container. Instead, use setComponentPopupMenu.
Alternatively, you could do the work yourself by adding a MouseListener whose mousePressed, mouseReleased and mouseClicked methods call isPopupTrigger and show. (It is vital that you do this in all three of those methods—different platforms have different conditions for showing popup menus.)
But really, using setComponentPopupMenu is easier.
So I'm making a simple program that jumps from panel to panel and am using an actionlistener Button to make the jump. What kind of method or operation do I use to jump from panel to panel?
I tried to use setVisible(true); under the action listener, but I get just a blanks screen. Tried using setContentPane(differentPanel); but that doesn't work.
ackage Com.conebind.Characters;
import Com.conebind.Tech.TechA16;
import Com.conebind.Overviews.OverviewA16;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Char_A16 extends JFrame {
private JButton combosButton16;
private JButton techButton16;
private JButton overviewButton16;
private JLabel Image16;
private JPanel panel16;
private JPanel panelOverviewA16;
public Char_A16() {
overviewButton16.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
OverviewA16 overview16 = new OverviewA16();
overview16.setVisible(true);
overview16.pack();
overview16.setContentPane(new Char_A16().panelOverviewA16);
}
});
techButton16.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//Todo
}
});
}
private void createUIComponents(){
Image16 = new JLabel(new ImageIcon("Android 16.png"));
}
public static void main (String[] args){
JFrame frame = new JFrame("Android 16");
frame.setContentPane(new Char_A16().panel16);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);}
}
The setContentPane(OverviewA16) doesn't work because there's not an object that defines the panel.
Please check this demo project showing how to use CardLayout with IntelliJ IDEA GUI Designer.
The main form has a method that switches between 2 forms displayed inside it:
public void showPanel(String id) {
final CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, id);
}
Both forms are added to the card layout during the main form initialization:
FormOne one = new FormOne();
one.setParentForm(this);
cardPanel.add(one.getPanel(), FORM_ONE);
FormTwo two = new FormTwo();
two.setParentForm(this);
cardPanel.add(two.getPanel(), FORM_TWO);
final CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, FORM_ONE);
A reference to the main parent form is passed to these 2 forms using setParentForm() method so that FormOne and FormTwo classes can access the showPanel() method of the MainForm.
In a more basic case you may have a button or some other control that switches the forms
located directly on the MainForm, then you may not need passing the main form reference to the subforms, but it can be still useful depending on your app logic.
Hello so i started learning java a week back and i basically started making a gui just to see how things work and i found a weird "bug" or i don't exactly understand how things work and it's not even a bug
i have a class called startPanel that makes a panel that is visible from the start
and it asks you as to what you wish to log in admin,user or a guest
this is startPanel:
package library;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/*
* this panel is responsible for the first opening panel and redirects you to your panel
*
*
*/
import javax.swing.*;
public class startPanel extends JFrame {
boolean adminState=false;
boolean userState=false;
boolean guestState=false;
JButton adminBut,userBut,guestBut ;
//start of constructor
public startPanel(){
//frame size,close when pressing x,title,and spawn at middle of the screen
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Welcome guest");
this.setLocationRelativeTo(null);
//making the panel
JPanel panel1 = new JPanel();
//making a label to fill things up it doesn't really do anything
JLabel startLabel = new JLabel("you wan't to log in as...");
//3 buttons for the user to click 1 only and the according frame will show up
adminBut = new JButton("Admin");
userBut = new JButton("User");
guestBut = new JButton("Guest");
//making an event handler for admin only so far just for test purposes
ListenForButton lForButton = new ListenForButton();
adminBut.addActionListener(lForButton);
//adding comps to the panel
panel1.add(startLabel);
panel1.add(adminBut);
panel1.add(userBut);
panel1.add(guestBut);
//adding the panel to the frame
this.add(panel1);
} // end of startPanel constructor
private class ListenForButton implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
/*probably not the correct way to do what i want to but just figured this might work
*it only works for admin button if the user presses the adminBut
*it will change the states and with a getter we can change each state
*from main accordingly
*/
if (event.getSource() == adminBut ){
adminState=true;
guestState=false;
userState= false;
}
}
} // end of Listen for button
//all getters for the states
public boolean getAdminState(){
return adminState;
}
public boolean getUserState(){
return guestState;
}
public boolean getGuestState(){
return userState;
}
}
this is main :
package library;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class mainLibrary {
public static void main(String[] args) {
adminPanel adminP = new adminPanel();
userPanel userP = new userPanel();
startPanel gui = new startPanel();
gui.setVisible(true);
while(true){
System.out.println(gui.getAdminState());
if (gui.getAdminState() == true) {
gui.setVisible(false);
userP.setVisible(true);
}
}
the problem now is that if i remove System.out.println(gui.getAdminState());
this does not work it doesn't even get in the if at all if it's false at start
if i don't remove it works correctly :/
so what is going on
this is adminPanel for the adminPanel if it matters
package library;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class adminPanel extends JFrame {
//start of adminPanel constructor
public adminPanel(){
//frame size,close when pressing x,title,and spawn at middle of the screen
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Admin panel area");
this.setLocationRelativeTo(null);
JPanel panel1 = new JPanel();
this.add(panel1);
} //end of admin constructor
}
This is not a good GUI design. Never use such active loop.
Remarks: use standard naming convention (uppercase/lowercase), and never call a frame a panel (this is too confusing).
A better design would be to have references to Panels to be activated in the startPanel and setting appropriate property reacting to button actions. Something like:
class StartFrame extends JFrame implements ActionListener {
private JFrame adminFrame;
private JFrame userFrame;
...
// add construtor to initialize adminFrame and userFrame appropriately
...
public void actionPerformed(ActionEvent e) {
if (e.getSource() == adminBut) {
this.setVisible(false);
adminFrame.setVisible(true);
}
if (e.getSource() == userBut) {
this.setVisible(false);
userFrame.setVisible(true);
}
}
}
I have 2 jframes, 1 is kinda like the main menu, i want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
I used the sout to see what really happens because it wasnt working, but i see that the level goes from 0 to 1 back to 0 and goes on and on, does someone know why and how to fix?
SpeelVeld frame = new SpeelVeld();
frame.setBounds(0,0,519,591);
frame.setLocationRelativeTo(null);
frame.getContentPane().setBackground(Color.WHITE);
frame.setTitle("RWINA");
frame.setVisible(true);
frame.setLevel(1);
this is in the main method of my original GameProject file.
How can i make a jdialog
I have 2 jframes, 1 is kinda like the main menu,
You shouldn't use 2 JFrames for this. The dependent sub-window, likely your main menu window, should in fact be a JDialog, probably a non-modal dialog from the looks of it.
I want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
and here's a big problem. Understand that in this code, you're creating a new SpeelVeld object, the stress being on the word new. Changing the state of this object will have no effect on the other SeelVeld object that is currently being displayed. Do do that, your second window will need a valid reference to the displayed SeelVeld object. How to do this will depend all on code not yet shown, but often it can be done simply by passing in the displayed SpeelVeld object into the main menu object by use of a constructor parameter or setter method.
For example:
import java.awt.Dialog.ModalityType;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
// JPanel for our main GUI
public class SpeelVeldFoo {
private static void createAndShowGui() {
// JPanel used by the main JFrame
SpeelVeldPanel speelVeldPanel = new SpeelVeldPanel();
// JPanel used by the main menu JDialog. Pass the above into it
MainMenuPanel mainMenuPanel = new MainMenuPanel(speelVeldPanel);
// create your JFrame
JFrame frame = new JFrame("Speel Veld");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(speelVeldPanel); // add the JPanel
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
// create your non-modal JDialog
JDialog menuDialog = new JDialog(frame, "Main Menu", ModalityType.MODELESS);
menuDialog.add(mainMenuPanel); // add the JPanel that holds its "guts"
menuDialog.pack();
menuDialog.setLocationByPlatform(true);
menuDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
#SuppressWarnings("serial")
class SpeelVeldPanel extends JPanel {
private int level = 1; // simple example just has a level int
private JLabel levelLabel = new JLabel("1"); // and displays it in a JLabel
public SpeelVeldPanel() {
add(new JLabel("Level:"));
add(levelLabel);
int ebGap = 50;
setBorder(BorderFactory.createEmptyBorder(ebGap, 2 * ebGap, ebGap, 2 * ebGap));
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
// whenever level is changed, update the display
this.level = level;
levelLabel.setText(String.valueOf(level));
}
}
// class for the JPanel held by the JDialog
#SuppressWarnings("serial")
class MainMenuPanel extends JPanel {
private JSpinner levelSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 5, 1));
private SpeelVeldPanel speelVeldPanel = null; // reference to the main GUI
// note the parameter.... you pass in the displayed main GUI so you can
// change it
public MainMenuPanel(final SpeelVeldPanel speelVeldPanel) {
this.speelVeldPanel = speelVeldPanel; // set the field
// respond when the spinner's data changes
levelSpinner.addChangeListener(new LevelListener());
add(new JLabel("Set the Speel Veld's level:"));
add(levelSpinner);
int ebGap = 10;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
}
private class LevelListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
// when the spinner's data changes
int level = (int) levelSpinner.getValue(); // get the data
speelVeldPanel.setLevel(level); // and send it to the main GUI
}
}
}
You'll note that I don't like extending JFrame or JDialog if I can avoid it. My feeling is that one can paint oneself into a corner by having your class extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding.
You probably want the JFrame to be the top-level container, then have a JPanel that holds your menu. The menu could be whatever you want, I'm using a JTextArea. Then, you need a JButton for the JPanel or JFrame that when pressed, changes the text in the JTextArea. Here is an implementation that you could work from. I'm using the ActionEvent as the trigger for when to mess with the JTextArea:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class SimpleSwing {
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
JPanel mainMenuPanel = new JPanel();
JTextArea textAttribute = new JTextArea("Original Text");
JButton changeAttributeButton = new JButton("Change Attribute");
changeAttributeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textAttribute.setText("Whatever new text you want");
}
});
mainMenuPanel.add(textAttribute);
mainMenuPanel.add(changeAttributeButton);
mainFrame.add(mainMenuPanel);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(500, 500);
mainFrame.setVisible(true);
}
}
I am trying to build a little program that has a main GUI with 2 buttons. One button closes the program, the other I want to open a new JPanel that will have text fields etc.
I would like to be able to make the buttons so they look like normal application buttons I guess, nice and square, equal size etc. etc., I am not sure how to do this though.
Also, I am unsure how to open a new JFrame from a button click.
GUI Code:
package practice;
public class UserInterface extends JFrame {
private JButton openReportSelection = new JButton("Open new Window");
private JButton closeButton = new JButton("Close Program");
private JButton getCloseButton() {
return closeButton;
}
private JButton getOpenReportSelection() {
return openReportSelection;
}
public UserInterface() {
mainInterface();
}
private void mainInterface() {
setTitle("Program Information Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel centerPanel = new JPanel(new GridLayout(0, 3));
centerPanel.add(openReportSelection);
centerPanel.add(closeButton);
getCloseButton().addActionListener(new Listener());
add(centerPanel, BorderLayout.CENTER);
setSize(1000, 200);
setVisible(true);
}
private void addReportPanel() {
JPanel reportPanel = createNewPanel();
getContentPane().add(reportPanel, BorderLayout.CENTER);
}
private JPanel createNewPanel() {
JPanel localJPanel = new JPanel();
localJPanel.setLayout(new FlowLayout());
return localJPanel;
}
}
ActionListener Class code:
package practice;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Listener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
}
EDIT: I think opening a new JPanel would be the way to go rather than a JFrame. What would be the best way to do this from a Jbutton click?
Start by using a different layout manager, FlowLayout or GridBagLayout might work better
JPanel centerPanel = new JPanel(new FlowLayout());
centerPanel.add(openReportSelection);
centerPanel.add(closeButton);
These layouts will honour the preferred sizes of your buttons
As for opening another window, well, you've already create one, so the process is pretty much the same. Having said that, you might consider having a look at The Use of Multiple JFrames: Good or Bad Practice? before you commit yourself to far.
A better approach might be to use a JMenuBar and JMenuItems to act as the "open" and "exit" actions. Take a look at How to Use Menus then you could use a CardLayout to switch between views instead, for example
From a pure design perspective (I know it's only practice, but perfect practice makes perfect), I wouldn't extend anything from JFrame and instead would rely on building your main GUIs around something like JPanel instead.
This affords you the flexibility to decide how to use these components, as you could add them to frames, applets or other components...
If you want your buttons to have the native Look and Feel (L&F), add the following to your program:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Instead of opening another JFrame, you'll want to instead use a JDialog, typically with modality set.
In Java, you can only extend one class and therefore you should consider carefully whether it is appropriate or not to extend another class. You could ask yourself, "Am I actually extending the functionality of JFrame?" If the answer is no, then you actually want to use an instance variable.
Below is an example program from the above recommendations:
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class MyApplication {
private JFrame myframe; // instance variable of a JFrame
private JDialog mydialog;
public MyApplication() {
super();
myframe = new JFrame(); // instantiation
myframe.setSize(new Dimension(400, 75));
myframe.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
JButton btnNewWindow = new JButton("Open New Window");
btnNewWindow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mydialog = new JDialog();
mydialog.setSize(new Dimension(400,100));
mydialog.setTitle("I got you! You can't click on your JFrame now!");
mydialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); // prevent user from doing something else
mydialog.setVisible(true);
}
});
myframe.getContentPane().add(btnNewWindow);
JButton btnCloseProgram = new JButton("Close Program :(");
btnCloseProgram.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myframe.dispose();
}
});
myframe.getContentPane().add(btnCloseProgram);
myframe.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MyApplication();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I am not sure from your question what do wou want to do. Do you want to open a new JFrame or do you want to add a JPanel to the existing frame.
To open a new JFrame using a button, create an instance of the JFrame in the actionPerformed method of the button. In your case it would look similar to this:
openReportSelection.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFrame frame = new JFrame();
// Do something with the frame
}
}
});
You're probably looking up to create and open a new JFrame. For this purpose, first you need to instantiate an object from JFrame Class. As an example, Let's instantiate a new JFrame with specific boundries.
JFrame testFrame = new testFrame();
verificationFrame.setBounds(400, 100, 250, 250);
Then you need to create your components like JButtons, Jlabels and so on, and next you should add them to your new testFrame object.
for example, let's create a Jlabel and add it testFrame:
JLabel testLbl = new JLabel("Ok");
testLbl.setBounds(319, 49, 200, 30);
testFrame.getContentPane().add(testLbl);
Now let's suppose you have a Jbutton which is named "jbutton" and by clicking it, a new JFrame object will be created and the Jlabel component will be added to it:
jButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFrame testFrame = new testFrame();
verificationFrame.setBounds(400, 100, 250, 250);
Label testLbl = new JLabel("Ok");
testLbl.setBounds(319, 49, 200, 30);
testFrame.getContentPane().add(testLbl);
}}});