I'm new to Java, I want to do the following:
The user selects an option from the JComboBox which will fire the following:
New panel shows up in the same frame, containing 5 tickboxes. Each tickbox has a value.
The user selects 2 tickboxes, clicks "Calculate"
New TextBox is fired with the sum of the values.
The user changes the selection from the ComboBox, the previous frame is removed and a new one shows up.
The idea above is a calculator, but a bit more complicated than the conventional one.
Your time and help will be much appreciated. I'm using the gui form in IntelliJ. Here is what I've got so far:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.ImageIcon;
public class CastCalculator {
private JPanel MainPanel;
private JLabel CastImage;
private JComboBox buidlingChoice;
private JComboBox procurementChoice;
private JCheckBox pMFoundationsCheckBox;
private JCheckBox pMFrameElementsCheckBox;
private JPanel House;
private JPanel fiveStorey;
private JPanel traditional;
private JPanel finalCalculation;
private JRadioButton radioButton1;
private JButton calculateButton;
double pmFoundationsValue;
private JPanel resultPanel;
String toString(double d) {
return null;
}
private CastCalculator(){
calculator();
}
private void calculator(){
House.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
JOptionPane.showMessageDialog(null, "Hi Michelle");
}
});
pMFoundationsCheckBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (pMFoundationsCheckBox.isSelected())
pmFoundationsValue = 1.5;
}
});
String pmFV = Double.toString( pmFoundationsValue );
calculateButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
}
private void houseComboBox {
String[] buildingStrings = {"House", "5-Storey Building", "10-Storey Building"};
String[] procurementStrings = {"Traditional", "2-D", "3-D"};
JComboBox<String> buildingList = new JComboBox<>( buildingStrings );
buildingList.setSelectedIndex( 3 );
buildingList.addActionListener( (ActionListener) this );
#Override
public void actionPerformed(ActionEvent Object e;
e) {
}
}
private void createUIComponents() {
CastImage = new JLabel( (new ImageIcon( "cast.png" )) );
}
public static void main(String[] args) {
JFrame mainFrame = new JFrame( "Cast PMV Calculator" );
mainFrame.setContentPane( new CastCalculator().calculator);
mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
mainFrame.pack();
//mainFrame.setSize(500,600);
mainFrame.setVisible( true );
}
}
Related
I cannot get my Jframe to close when a user hits the (X) button. I tried many ways to do them but none of them work.
I tried:
JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Nothing happens. My main class extends jframe and implements action listener. What am I doing wrong?
My code:
package com.xflare.Bot;
import static java.lang.System.out;
import java.awt.*;
import java.lang.String;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main extends JFrame implements ActionListener{
private static Frame frame;
private static boolean debug = true;
private static boolean enabled = true;
private static JButton exitbutton; // reference to the button object
private static JButton webbutton; // reference to the button object
private static JButton aboutbutton; // reference to the button object
public static void main(String[] args) {
new Main().start();
}
private void start(){
//start up
printSystem("starting");
//create frame
printSystem("Creating a frame...");
createFrame();
//create button(s)
createQuitButton();
createWebButton();
createAboutButton();
//Spawn init.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}
private void createFrame(){
Main.frame = new Frame("app");
frame.setSize(600, 300);
}
private void createQuitButton(){
exitbutton = new JButton("Exit!");
getFrame().setLayout(null);
exitbutton.setBounds(225,45,150,75);//setBounds(x,y,width,height)
exitbutton.setActionCommand("exit");
exitbutton.addActionListener(this);
getFrame().add(exitbutton);
}
private void createWebButton(){
webbutton = new JButton("Open hacked browser");
getFrame().setLayout(null);
webbutton.setBounds(225,130,150,75);//setBounds(x,y,width,height)
webbutton.setActionCommand("web");
webbutton.addActionListener(this);
getFrame().add(webbutton);
}
private void createAboutButton(){
aboutbutton = new JButton("About");
getFrame().setLayout(null);
aboutbutton.setBounds(225,215,150,75);//setBounds(x,y,width,height)
aboutbutton.setActionCommand("about");
aboutbutton.addActionListener(this);
getFrame().add(aboutbutton);
}
private Frame getFrame(){
return Main.frame;
}
public void actionPerformed(ActionEvent e) {
String actionCommand = ((JButton) e.getSource()).getActionCommand();
printDebug("Button " + actionCommand + " was pressed.");
if(actionCommand.equals("exit")){
exitbutton.setVisible(false);
shutdown();
}
else if(actionCommand.equals("about")){
aboutbutton.setVisible(false);
webbutton.setVisible(false);
exitbutton.setVisible(false);
showAbout();
}
else{
printCritical("Unknown button pressed!");
}
}
private void showAbout(){
}
private void shutdown(){
printSystem("Attempting to shut down...");
enabled = false;
printSystem("Shut down successful!");
System.exit(0);
}
private boolean debugEnabled(){
return debug;
}
private String getVersion(){
return "1.0.0";
}
private String getCodename(){
return "[BeastReleased]";
}
private static void printSystem(String var){
out.println("System> " + var);
}
private static void printError(String var){
out.println("Error> " + var);
}
private static void printCritical(String var){
out.println("Critical> " + var);
}
private void printDebug(String var){
if(debugEnabled()) {
out.println("Debug> " + var);
}
}
}
Link to same code: http://pastebin.com/1fDbjm74
This: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
needs to be called on the JFrame that you're actually displaying, Main.frame. You're not doing this.
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setVisible(true);
You've got too many Frame / JFrames. Your class extends JFrame but you're not displaying it. You've also got a Frame variable called frame, (NOT a JFrame variable) that you are displaying, and of course since this is not a JFrame, you can't make JFrame method calls, like the one above on it.
Simplify: create ONE JFrame not a Frame, and call this method on it and set it visible. So either get rid of the frame variable and use the class itself, the this, as your JFrame, and display it, or don't have your class extend JFrame and use your frame variable, but make it a JFrame object not a Frame object, since Frame does not have the setDefaultCloseOperation(...) method.
Also you're over-using static modifiers where they shouldn't be used. All your fields should be instance (non-static) fields.
Also, use of null layouts and setBounds will bite you in the end. For instance when I run your program, portions of the middle button's text are missing because its size has been artificially constrained in a bad way. Much better is to us layout managers to your advantage. For example:....
Please have a look at this program structure:
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class MyMain extends JPanel {
public static final String MENU_PANEL = "MENU";
public static final String ABOUT_PANEL = "About";
private CardLayout cardLayout = new CardLayout();
public MyMain() {
JPanel aboutPanel = new JPanel(new GridBagLayout());
JLabel aboutLabel = new JLabel("About");
aboutLabel.setFont(aboutLabel.getFont().deriveFont(Font.BOLD, 32));
aboutPanel.add(aboutLabel);
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
buttonPanel.add(createButton(new ExitAction("Exit!", KeyEvent.VK_X)));
buttonPanel.add(createButton(new OpenBrowserAction("Open Hacked Browser", KeyEvent.VK_O)));
buttonPanel.add(createButton(new AboutAction("About", KeyEvent.VK_A, this)));
JPanel menuPanel = new JPanel(new GridBagLayout());
int ebGap = 40;
menuPanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
menuPanel.add(buttonPanel);
setLayout(cardLayout);
add(menuPanel, MENU_PANEL);
add(aboutPanel, ABOUT_PANEL);
}
private JButton createButton(Action action) {
JButton button = new JButton(action);
Font btnFont = button.getFont().deriveFont(Font.BOLD, 20);
button.setFont(btnFont);
return button;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("My Main Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyMain());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
public void showPanel(String cardLayoutKey) {
cardLayout.show(this, cardLayoutKey);
}
}
class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component comp = (Component) e.getSource();
if (comp != null) {
Window win = SwingUtilities.getWindowAncestor(comp);
if (win != null) {
win.dispose();
}
}
}
}
class OpenBrowserAction extends AbstractAction {
public OpenBrowserAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open Browswer");
}
}
class AboutAction extends AbstractAction {
private MyMain myMain;
public AboutAction(String name, int mnemonic, MyMain myMain) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myMain = myMain;
}
#Override
public void actionPerformed(ActionEvent e) {
if (myMain != null) {
myMain.showPanel(MyMain.ABOUT_PANEL);
}
}
}
You are calling the setDefaultCloseOperation method on the wrong place. Here's what you should do:
private void start(){
//start up
printSystem("starting");
//create frame
printSystem("Creating a frame...");
createFrame();
//Spawn init.
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}
private void createFrame(){
Main.frame = new Frame("app");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 300);
}
I have two frames with contents . The first one has a jlabel and jbutton which when it is clicked it will open a new frame. I need to repaint the first frame or the panel that has the label by adding another jlabel to it when the second frame is closed.
//Edited
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class FirstFrame extends JPanel implements KeyListener{
private static String command[];
private static JButton ok;
private static int count = 1;
private static JTextField text;
private static JLabel labels[];
private static JPanel p ;
private static JFrame frame;
public int getCount(){
return count;
}
public static void createWindow(){
JFrame createFrame = new JFrame();
JPanel panel = new JPanel(new GridLayout(2,1));
text = new JTextField (30);
ok = new JButton ("Add");
ok.requestFocusInWindow();
ok.setFocusable(true);
panel.add(text);
panel.add(ok);
text.setFocusable(true);
text.addKeyListener(new FirstFrame());
createFrame.add(panel);
createFrame.setVisible(true);
createFrame.setSize(600,300);
createFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
createFrame.setLocationRelativeTo(null);
createFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.out.println(command[count]);
if(command[count] != null){
p.add(new JLabel("NEW LABEL"));
p.revalidate();
p.repaint();
count++;
System.out.println(count);
}
}
});
if(count >= command.length)
count = 1;
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(command[count] == null)
command[count] = text.getText();
else
command[count] = command[count]+", "+text.getText();
text.setText("");
}
});
}
public FirstFrame(){
p = new JPanel();
JButton create = new JButton ("CREATE");
command = new String[2];
labels = new JLabel[2];
addKeyListener(this);
create.setPreferredSize(new Dimension(200,100));
//setLayout(new BorderLayout());
p.add(new JLabel("dsafsaf"));
p.add(create);
add(p);
//JPanel mainPanel = new JPanel();
/*mainPanel.setFocusable(false);
mainPanel.add(create);
*/
create.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
createWindow();
}
});
//add(mainPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
frame = new JFrame();
frame.add(new FirstFrame());
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
if(ok.isDisplayable()){
ok.doClick();
return;}
}
}
}
});
}
}
As per my first comment, you're better off using a dialog of some type, and likely something as simple as a JOptionPane. For instance in the code below, I create a new JLabel with the text in a JTextField that's held by a JOptionPane, and then add it to the original GUI:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class FirstPanel2 extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 300;
private JTextField textField = new JTextField("Hovercraft rules!", 30);
private int count = 0;
public FirstPanel2() {
AddAction addAction = new AddAction();
textField.setAction(addAction);
add(textField);
add(new JButton(addAction));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class AddAction extends AbstractAction {
public AddAction() {
super("Add");
}
#Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
final JTextField someField = new JTextField(text, 10);
JPanel panel = new JPanel();
panel.add(someField);
int result = JOptionPane.showConfirmDialog(FirstPanel2.this, panel, "Add Label",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
JLabel label = new JLabel(someField.getText());
FirstPanel2.this.add(label);
FirstPanel2.this.revalidate();
FirstPanel2.this.repaint();
}
}
}
private static void createAndShowGui() {
FirstPanel2 mainPanel = new FirstPanel2();
JFrame frame = new JFrame("My Gui");
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();
}
});
}
}
Also, don't add KeyListeners to text components as that is a dangerous and unnecessary thing to do. Here you're much better off adding an ActionListener, or as in my code above, an Action, so that it will perform an action when the enter key is pressed.
Edit
You ask:
Just realized it is because of the KeyListener. Can you explain please the addAction ?
This is functionally similar to adding an ActionListener to a JTextField, so that when you press enter the actionPerformed(...) method will be called, exactly the same as if you pressed a JButton and activated its ActionListener or Action. An Action is like an "ActionListener" on steroids. It not only behaves as an ActionListener, but it can also give the button its text, its icon and other properties.
Dear Friends of StackOverFlow,
I've been trying to solve this problem for 2 weeks. thank you in advance for your help.
What I'm trying to do:
I have a CardLayout that switches between different JPanels.
Pan1 has different buttons that are supposed to become visible if a variable Level1 is set to "1"
Pan2 is launched by Pan1 and has a button that sets the variable Level1 to "1" and a button to subsequently go back to Pan1
when I go back to Pan1 I should now see a button because the variable is 1
The Problem:
the variable is set to 1 correctly but when I go back to Pan1 the button is not visible. I tried repaint, revalidate, but nothing seems to work
my code
package prove3;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PRINCIPAL extends Level1{
JFrame MainWindow;
JPanel panelCont;
Pan1 Pan1Window;
Pan2 Pan2Window;
CardLayout cards;
public PRINCIPAL(){
MainWindow = new JFrame("Game Window");
panelCont = new JPanel();
cards = new CardLayout();
Pan1Window = new Pan1(cards, panelCont, Level1Completed);
Pan2Window = new Pan2(Pan1Window, cards, panelCont, Level1Completed);
panelCont.setLayout(cards);
panelCont.add(Pan1Window, "1");
panelCont.add(Pan2Window, "2");
cards.show(panelCont, "1");
MainWindow.add(panelCont);
MainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
MainWindow.setSize(800, 800);
MainWindow.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new PRINCIPAL();
}
});
}
}
class Level1 extends JPanel{
static int Level1Completed = 0;
public void setLevel1Completed (int newLevel1Completed){
Level1Completed = newLevel1Completed;
}
public int getLevel1Completed(){
return Level1Completed;
}
}
class Pan1 extends Level1 {
JPanel panelCont;
CardLayout LayoutPan1;
JLabel label;
JButton OpenPan2;
JButton buttonLevel2;
int L1Completed;
public Pan1(
final CardLayout LayoutPan1,
final JPanel panelCont,
final int Level1Completed)
{
this.L1Completed = super.getLevel1Completed();
this.panelCont = panelCont;
this.LayoutPan1 = LayoutPan1;
OpenPan2 = new JButton("Open Pan2 Window");
buttonLevel2 = new JButton("Progress to Level 2");
OpenPan2.addActionListener
(new ActionListener()
{
public void actionPerformed (ActionEvent GoToPan2)
{
if (GoToPan2.getSource() == OpenPan2){
LayoutPan1.show(panelCont, "2");
}
}
}
);
add(OpenPan2);
//this printout is to see that, at the beginning, the Level1 variable is set to 0 (see the command line)
System.out.println(getLevel1Completed());
//this is where the problem is: what I want is that this button is initially not visible as the variable is set to 0
//but when, in the next pan, I'll set it to 1, this button becomes visible
if (super.getLevel1Completed()==1){
add(buttonLevel2);
buttonLevel2.setVisible(true);
invalidate();
revalidate();
}
setBackground(Color.GREEN);
}
}
class Pan2 extends Level1 {
JPanel Pan1Window;
CardLayout LayoutPan1Window;
JPanel panelCont;
JButton OpenPan1;
JButton L1Done;
int L1Completed;
public Pan2(
final JPanel Pan1Window,
final CardLayout LayoutPan1Window,
final JPanel panelCont,
final int L1Completed
){
this.L1Completed = super.getLevel1Completed();
OpenPan1 = new JButton("Go back to Pan 1");
OpenPan1.addActionListener
(new ActionListener()
{
public void actionPerformed(ActionEvent ApriFinestraLancio)
{
if(ApriFinestraLancio.getSource()==OpenPan1){
LayoutPan1Window.show(panelCont, "1");
}
}
}
);
add(OpenPan1);
L1Done = new JButton("Set Level 1 as Completed");
L1Done.addActionListener
(new ActionListener()
{
public void actionPerformed(ActionEvent SettaL1Complet)
{
setLevel1Completed(1);
System.out.println(getLevel1Completed());//this print shows that the value of the variable is correctly changed to 1
}
}
);
add(L1Done);
setBackground(Color.RED);
}
}
any help is really welcome
if (super.getLevel1Completed()==1){
add(buttonLevel2);
buttonLevel2.setVisible(true);
invalidate();
revalidate();
}
The code should be called where the level1Completed is set. It could be inside the setter itself or in the actionPerfomed() where you call
setLevel1Completed(1);
System.out.println(getLevel1Completed());
No need to call invalidate() and revalidate(). The revalidate is enough. I would suggest to add the button initially and make it invisible. Thus all you need there is to call
buttonLevel2.setVisible(super.getLevel1Completed()==1); to change the button's visibility
The Problem is, that you only check if level1 is set in the constructor of Pan1. So if you call show LayoutPan1Window.show(panelCont, "1"); the variable is not checked anymore.
A solution would be to implement a ComponentListener for Pan1. The ComponentListener provides a method onComponentShown() which gets called every time the component gets shown. In this mehtod you could perform the check of the level1 variable. The code could look like this:
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PRINCIPAL extends Level1 {
JFrame MainWindow;
JPanel panelCont;
Pan1 Pan1Window;
Pan2 Pan2Window;
CardLayout cards;
public PRINCIPAL() {
MainWindow = new JFrame("Game Window");
panelCont = new JPanel();
cards = new CardLayout();
Pan1Window = new Pan1(cards, panelCont, Level1Completed);
Pan2Window = new Pan2(Pan1Window, cards, panelCont, Level1Completed);
panelCont.setLayout(cards);
panelCont.add(Pan1Window, "1");
panelCont.add(Pan2Window, "2");
cards.show(panelCont, "1");
MainWindow.add(panelCont);
MainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
MainWindow.setSize(800, 800);
MainWindow.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new PRINCIPAL();
}
});
}
}
class Level1 extends JPanel {
static int Level1Completed = 0;
public void setLevel1Completed(int newLevel1Completed) {
Level1Completed = newLevel1Completed;
}
public int getLevel1Completed() {
return Level1Completed;
}
}
class Pan1 extends Level1 implements ComponentListener {
JPanel panelCont;
CardLayout LayoutPan1;
JLabel label;
JButton OpenPan2;
JButton buttonLevel2;
int L1Completed;
public Pan1(final CardLayout LayoutPan1, final JPanel panelCont,
final int Level1Completed) {
this.L1Completed = super.getLevel1Completed();
this.panelCont = panelCont;
this.LayoutPan1 = LayoutPan1;
addComponentListener(this);
OpenPan2 = new JButton("Open Pan2 Window");
buttonLevel2 = new JButton("Progress to Level 2");
OpenPan2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent GoToPan2) {
if (GoToPan2.getSource() == OpenPan2) {
LayoutPan1.show(panelCont, "2");
}
}
});
add(OpenPan2);
// this printout is to see that, at the beginning, the Level1 variable
// is set to 0 (see the command line)
System.out.println(getLevel1Completed());
setBackground(Color.GREEN);
}
#Override
public void componentHidden(ComponentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void componentMoved(ComponentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void componentResized(ComponentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void componentShown(ComponentEvent e) {
// this is where the problem is: what I want is that this button is
// initially not visible as the variable is set to 0
// but when, in the next pan, I'll set it to 1, this button becomes
// visible
if (super.getLevel1Completed() == 1) {
add(buttonLevel2);
buttonLevel2.setVisible(true);
invalidate();
revalidate();
}
}
}
class Pan2 extends Level1 {
JPanel Pan1Window;
CardLayout LayoutPan1Window;
JPanel panelCont;
JButton OpenPan1;
JButton L1Done;
int L1Completed;
public Pan2(final JPanel Pan1Window, final CardLayout LayoutPan1Window,
final JPanel panelCont, final int L1Completed) {
this.L1Completed = super.getLevel1Completed();
OpenPan1 = new JButton("Go back to Pan 1");
OpenPan1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ApriFinestraLancio) {
if (ApriFinestraLancio.getSource() == OpenPan1) {
LayoutPan1Window.show(panelCont, "1");
}
}
});
add(OpenPan1);
L1Done = new JButton("Set Level 1 as Completed");
L1Done.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent SettaL1Complet) {
setLevel1Completed(1);
System.out.println(getLevel1Completed());// this print shows
// that the value of
// the variable is
// correctly changed
// to 1
}
});
add(L1Done);
setBackground(Color.RED);
}
}
after looking for an answer for 3 hours, I am just about to give up on this idea:
I am making an application that displays the followers of a Twitch streamer.
A couple of features i am trying to add:
the display frame is a separate window from the controls frame.
I am trying to use (JFrame as display window) (JDialog as controls frame)
And furthermore: Settings is in another JDialog (this one has Modal(true))
Settings needs to be able to send the JFrame information such as: "username" and "text color"
And the settings JDialog will only pop up from clicking "settings" on the controls JDialog.
It will setVisible(false) when you click "save settings" or the X.
On the controls JDialog (b_console) needs to receive error messages and info like that.
And on the same JDialog, "filler" needs to receive follower count and things like that.
Here follows my code involving the transfers listed above:
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;
public class JavaFollowerNotifier extends JFrame implements ComponentListener
{
Settings settings = new Settings();
ControlPanel ctrlPnl = new ControlPanel();
public JavaFollowerNotifier()
{
try
{
settings.readSettings();
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void grabFollower()
{
ctrlPnl.b_console.setText("Retrieving Info...");
try
{
URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");
ctrlPnl.b_console.setText("Retrieved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void grabStats()
{
ctrlPnl.b_console.setText("Retrieving Info...");
try
{
URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");
ctrlPnl.filler.setText("Followers: " + totalFollowers + "\nLatest: " + lastFollower);
ctrlPnl.b_console.setText("Retrieved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void componentMoved(ComponentEvent arg0)
{
//this is only to *attach this JDialog to the JFrame and make it move together my plan is to have it undecorated as well
int x = this.getX() + this.getWidth();
int y = this.getY();
ctrlPnl.movePanel(x, y);
}
public void paint(Graphics g)
{
if(clearPaint == false)
{
//any "savedSettings[n]" are saved in Settings.java (just not in this version)
g.setColor(Color.decode(savedSettings[3]));
scaledFont = scaleFont(follower + " followed!", bounds, g, new Font(savedSettings[2], Font.PLAIN, 200));
}
}
}
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Settings extends JDialog implements ActionListener
{
JavaFollowerNotifier jfollow = new JavaFollowerNotifier();
ControlPanel ctrlPnl = new ControlPanel();
//here are the settings mention above
String[] savedSettings = {"imgs/b_b.jpg","username","font","color","Nightbot"};
public Settings()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void saveSettings()
{
savedSettings[4] = jfollow.lastFollower;
try
{
PrintWriter save = new PrintWriter("config.cfg");
ctrlPnl.b_console.setText("Saving...");
for(int i = 0; i < 5; i++)
{
save.println(savedSettings[i]);
}
save.close();
ctrlPnl.b_console.setText("Saved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
canClose = false;
}
readSettings();
this.repaint();
}
public void readSettings()
{
ctrlPnl.b_console.setText("Loading...");
try
{
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
jfollow.lastFollower = savedSettings[4];
try
{
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
ctrlPnl.b_console.setText("Loaded Settings");
}
}
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ControlPanel extends JDialog implements ActionListener
{
public ControlPanel()
{
try
{
}
catch (Exception e)
{
b_console.setText("Error");
System.out.println(e);
}
}
public void movePanel(int x, int y)
{
//here is where i *attach the JDialog to the JFrame
controlPanel.setLocation(x, y);
}
public void actionPerformed(ActionEvent ie)
{
if(ie.getSource() == b_settings)
{
settings.frame.setVisible(true);
}
}
}
I tried to fix your program, but I wasn't too sure about its flow. So I created another simple one. What I did was pass the labels from the main frame to the dialogs' constructors. In the dialog, I took those labels and changed them with text entered in their text fields. If you hit enter after writing text from the dialog, you'll see the text in the frame change
public class JavaFollowerNotifier1 extends JFrame{
private JLabel controlDialogLabel = new JLabel(" ");
private JLabel settingDialogLabel = new JLabel(" ");
private ControlDialog control;
private SettingsDialog settings;
public JavaFollowerNotifier1() {
control = new ControlDialog(this, true, controlDialogLabel);
settings = new SettingsDialog(this, true, settingDialogLabel);
....
class ControlDialog extends JDialog {
private JLabel label;
public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
....
class SettingsDialog extends JDialog {
private JLabel label;
public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
Test it out and let me know if you have any questions
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class JavaFollowerNotifier1 extends JFrame{
private JLabel controlDialogLabel = new JLabel(" ");
private JLabel settingDialogLabel = new JLabel(" ");
private JButton showControl = new JButton("Show Control");
private JButton showSetting = new JButton("Show Settings");
private ControlDialog control;
private SettingsDialog settings;
public JavaFollowerNotifier1() {
control = new ControlDialog(this, true, controlDialogLabel);
settings = new SettingsDialog(this, true, settingDialogLabel);
showControl.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
control.setVisible(true);
}
});
showSetting.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
settings.setVisible(true);
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(showControl);
buttonPanel.add(showSetting);
add(buttonPanel, BorderLayout.SOUTH);
add(controlDialogLabel, BorderLayout.NORTH);
add(settingDialogLabel, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JavaFollowerNotifier1();
}
});
}
}
class ControlDialog extends JDialog {
private JLabel label;
private JTextField field = new JTextField(15);
private JButton button = new JButton("Close");
private String s = "";
public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
setLayout(new BorderLayout());
add(field, BorderLayout.NORTH);
add(button, BorderLayout.CENTER);
pack();
setLocationRelativeTo(frame);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
s = field.getText();
label.setText("Message from Control Dialog: " + s);
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
ControlDialog.this.setVisible(false);
}
});
}
}
class SettingsDialog extends JDialog {
private JLabel label;
private JTextField field = new JTextField(15);
private JButton button = new JButton("Close");
private String s = "";
public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
setLayout(new BorderLayout());
add(field, BorderLayout.NORTH);
add(button, BorderLayout.CENTER);
pack();
setLocationRelativeTo(frame);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
s = field.getText();
label.setText("Message from Settings Dialog: " + s);
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
SettingsDialog.this.setVisible(false);
}
});
}
}
Typically when I build GUI's which use modal dialogs to gather user input, I build my own class, which extends the JDialog or in some cases a JFrame. In that class I expose a getter method for an object which I usually call DialgResult. This object acts as the Model for the input I gather from the user. In the class that has the button, or whatever control which triggers asking the user for the information, I create it, show it as a modal dialog, then when it is closed, I retrieve the object using that same getter.
This is a very primitive example:
package arg;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class asdfas extends JFrame {
public static void main(String[] args) {
asdfas ex = new asdfas();
ex.setVisible(true);
}
public asdfas() {
init();
}
private void init() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100,100,200,200);
final JButton button = new JButton("Show modal dialog");
button.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Dialog d = new Dialog();
d.setVisible(true);
button.setText(d.getDialogResult().value);
revalidate();
repaint();
}
});
this.add(button);
}
class DialogResult {
public String value;
}
class Dialog extends JDialog {
JTextField tf = new JTextField(20);
private DialogResult result = new DialogResult();
public Dialog() {
super();
init();
}
private void init() {
this.setModal(true);
this.setSize(new Dimension(100,100));
JButton ok = new JButton("ok");
ok.addActionListener( new ActionListener () {
#Override
public void actionPerformed(ActionEvent arg0) {
result = new DialogResult();
result.value = tf.getText();
setVisible(false);
}
});
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(tf);
p.add(ok);
this.add(p);
}
public DialogResult getDialogResult() {
return result;
}
}
}
I'm having a JTextField problem. I am needing to get text from a JTextField and modify it later in a JDialog. I am using the same variable for the JTextField. As long as you don't enter the dialog, the string printed is whatever you entered in the text field. If you enter a string in the dialog, it will only print that string until you change it again in the dialog (renders the primary text field useless). I can fix this by adding a separate variable, but would like to try to avoid unnecessary declarations. I was under the impression that this shouldn't matter since I'm creating a new JTextField object and also disposing of the dialog. Am I missing something? Any thoughts?
Here is a mock up of my problem.
import java.awt.event.*;
import javax.swing.*;
public class textfield extends JPanel {
private JTextField textfield;
private JButton printButton, dialogButton, okayButton;
private static JFrame frame;
public static void main(String[] args) {
frame = new JFrame();
frame.setSize(200,200);
frame.getContentPane().add(new textfield());
frame.setVisible(true);
}
private textfield() {
textfield = new JTextField(10);
add(textfield);
((AbstractButton) add(printButton = new JButton("Print"))).addActionListener(new printListener());
((AbstractButton) add(dialogButton = new JButton("Dialog"))).addActionListener(new dialogListener());
}
private class printListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String string = null;
string = textfield.getText();
System.out.println(string);
}
}
private class dialogListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
final JDialog dialog = new JDialog(frame, "Dialog", true);
JPanel p = new JPanel();
textfield = new JTextField(10);
p.add(textfield);
p.add(okayButton = new JButton(new AbstractAction("Okay") {
public void actionPerformed(ActionEvent e) {
String string = null;
string = textfield.getText();
System.out.println(string);
dialog.dispose();
}
}));
dialog.add(p);
dialog.pack();
dialog.setVisible(true);
}
}
}
you need to make JTextField inside the dialog, because when you are using one textfield, your main panel will point to new JTextField that was created in child dialog that was disposed when you press okey button (destroyed all its components). so don't change panel textfield pointer to new textfield object in disposed window.
your variable private JTextField textfield; is used twice, firstly for JFrame, and second time for JDialod, little bit changed ..
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MyTextfield extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField textfield, textfield1; //added new variable
private JButton printButton, dialogButton, okayButton;
private static JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {//added initial thread
#Override
public void run() {
frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//added default close operation
frame.getContentPane().add(new MyTextfield());
frame.setVisible(true);
}
});
}
private MyTextfield() {
textfield = new JTextField(10);
add(textfield);
((AbstractButton) add(printButton = new JButton("Print"))).addActionListener(new printListener());
((AbstractButton) add(dialogButton = new JButton("Dialog"))).addActionListener(new dialogListener());
}
private class printListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String string = null;
string = textfield.getText();
System.out.println(string);
}
}
private class dialogListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
final JDialog dialog = new JDialog(frame, "Dialog", true);
JPanel p = new JPanel();
textfield1 = new JTextField(10);
p.add(textfield1);
p.add(okayButton = new JButton(new AbstractAction("Okay") {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
String string = null;
textfield.setText(textfield1.getText());
System.out.println(string);
dialog.dispose();
}
}));
dialog.add(p);
dialog.pack();
dialog.setVisible(true);
}
}
}