Changing the visibilty of a label - java

i'm new to Java and experience a little bit with the WindowBuilder. I want to change the visibility of a different components like labels or textfields. So I wrote an example code: the function is, when I click on the button btnAnzahl the boolean bNoteVis is set to true in the method uebernehmen and bNoteVis is used as the variable to change the visibility of the label lblNote.
When I click on the button the message True is shown on the textfield tfNote but the label lblNote is still not visible.
Can somebody tell me how I can change the visibility like this because I want to change it with many components in multiple events.
package gui;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Notenbilanz_2 extends JFrame {
private JPanel contentPane;
private JTextField tfAnzahl;
private JTextField tfNote;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Notenbilanz_2 frame = new Notenbilanz_2();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Notenbilanz_2() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblAnzahl = new JLabel("Noten Anzahl");
lblAnzahl.setBounds(10, 11, 87, 14);
contentPane.add(lblAnzahl);
tfAnzahl = new JTextField();
tfAnzahl.setBounds(10, 31, 104, 20);
contentPane.add(tfAnzahl);
tfAnzahl.setColumns(10);
JLabel lblNote = new JLabel("1.Note");
lblNote.setVisible(bNoteVis);
lblNote.setBounds(10, 68, 87, 16);
contentPane.add(lblNote);
tfNote = new JTextField();
tfNote.setBounds(10, 95, 104, 20);
contentPane.add(tfNote);
tfNote.setColumns(10);
JButton btnAnzahl = new JButton("Umrechnen");
btnAnzahl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
uebernehmen();
if (bNoteVis) {
tfNote.setText("True");
}
}
});
btnAnzahl.setBounds(159, 28, 100, 26);
contentPane.add(btnAnzahl);
JButton btnNote = new JButton("Umrechnen");
btnNote.setBounds(159, 92, 100, 26);
contentPane.add(btnNote);
}
boolean bNoteVis = false;
private void uebernehmen() {
bNoteVis = true;
}
}

You've got some "magic thinking" going on. To wit:
You've set the visibility of the component based on a boolean variable
You expect the visibility of the component to magically change when the boolean variable changes -- but the component has no idea, no notification that this change has occurred, and so this is guaranteed to fail.
To get success, you will need to change the visibility of the component itself from within a listener. In other words, within the ActionListener, you will need to call .setVisible(true/false) on the component of interest.
btnAnzahl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
uebernehmen();
lblNote.setVisible(bNoteVis);
}
});
Other unrelated issues:
doing this, contentPane.setLayout(null);, and this, lblNote.setBounds(10, 68, 87, 16); will lead to siginficant frustration over time as it leads to inflexible GUI's that might look sort-of OK on one platform, but not OK on others, and that are hard to extend and modify. Much better to learn and use layout managers
If your goal is to change multiple components, then best to swap components using a CardLayout. Have a look at the CardLayout Tutorial for the details on how to use this tool.
Also, rather than toggle a JLabel's visibility, I'd change its text so that it still takes up space on the GUI.
For example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Notenbilanz3 extends JPanel {
private static final String LABEL_TEXT = "Noten Anzahl";
private JLabel lblNote = new JLabel(LABEL_TEXT);
private JTextField txtField1 = new JTextField(10);
private JCheckBox checkBox = new JCheckBox("Check Box", true);
public Notenbilanz3() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridwidth = 2;
gbc.insets = new Insets(3, 3, 3, 3);
add(lblNote, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
add(txtField1, gbc);
gbc.gridx = 1;
add(checkBox, gbc);
checkBox.addItemListener(l -> {
String text = l.getStateChange() == ItemEvent.SELECTED ? LABEL_TEXT : " ";
lblNote.setText(text);
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()-> {
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Notenbilanz3());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

Related

How do i add another button in JButton

I have 1 button i. but i need another. i added another JFrame and made a new class making the button. whenever i do
frame.add(new TestButton());
it never works. i already have
frame.add(new TestPanel());
which works. but its the only working one.
here is my TestButton code
package App.Gui.Buttons;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import App.Gui.Event.ExitEvent;
public class TestButton extends JPanel {
public TestButton() {
setLayout(new GridBagLayout());
JButton button = new JButton();
button.setBackground(new Color(0, 0, 0, 0));
button.setForeground(new Color(0, 0, 0, 0));
button.setBorderPainted(false);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ExitEvent.exit();
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.insets = new Insets(20, 50, 20, 50);
add(button, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
JPanel contentPane = new JPanel(new GridBagLayout());
contentPane.setBackground(Color.GREEN);
contentPane.add(new JLabel("Books app"));
add(contentPane, gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(1200, 750);
}
public static void addButton() {
new TestButton();
}
}
i need to add another button to do more stuff like you would need in a software. but it either never starts or, it bugs the buttons.
pls help.
A JPanel can't be shown in of itself. It needs to be added to a container hierarchy which is backed by a window based class, like JFrame.
This is a pretty basic concept, which suggests that you might be better off spending some time going through Creating a GUI With Swing, especially How to Make Frames (Main Windows)
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestButton());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Also, JFrame uses a BorderLayout by default, so you'll only be able to present a single component at each of it's five available positions.
So, if instead, you used a GridLayout, you could get multiple instances of TestButton on the window at the same time, for example
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(2, 1));
frame.add(new TestButton());
frame.add(new TestButton());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Now, Swing components also don't support alpha based colors, they are either opaque or they are not (no translucency - you can fake it, but that's beyond the scope)
So, I'd modify you code to look more like...
JButton button = new JButton();
//button.setBackground(new Color(0, 0, 0, 0));
//button.setForeground(new Color(0, 0, 0, 0));
button.setBorderPainted(false);
button.setOpaque(false);
button.setContentAreaFilled(false);
Also, good luck on been able to click that button by the way
Full code...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestButton extends JPanel {
public TestButton() {
setLayout(new GridBagLayout());
JButton button = new JButton();
// button.setBackground(new Color(0, 0, 0, 0));
// button.setForeground(new Color(0, 0, 0, 0));
button.setBorderPainted(false);
button.setOpaque(false);
button.setContentAreaFilled(false);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//ExitEvent.exit();
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.insets = new Insets(20, 50, 20, 50);
add(button, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
JPanel contentPane = new JPanel(new GridBagLayout());
contentPane.setBackground(Color.GREEN);
contentPane.add(new JLabel("Books app"));
add(contentPane, gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(1200, 750);
}
}
There are also issues with updating a realised window (adding/removing components once the window is visible on the screen). Swing is lazy and you are required to request a layout and paint pass on the container you've modified (invalidate and repaint).
But you might find CardLayout more suitable to your needs instead - but since we don't have a runnable example, it's hard to know

How do you add a JPanel from another class to a panel with CardLayout?

I'm working on a group project and I'm the one making the GUI figuring it'd be good to practice with it. The program is supposed to be a pizza ordering system (pretty standard stuff) and what I'm trying to accomplish is that I have a main class that creates an application window. Inside this window is a panel that uses CardLayout with a button that when pressed calls another JPanel from another class dedicated specifically to that panel and places it as a card in the layout to be swapped back and forth from as normal.
What I have so far are the different panels I wish to call and the main class which has the window and main card panel. I can have it swap easily between panels created within the main class but when I try to use the panels from the other classes it just swaps to a blank panel when it should show the other class's panel.
The main class
package PizzaGUI;
import java.awt.EventQueue;
import java.awt.CardLayout;
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Font;
public class PizzaSystem {
private JFrame frame;
Toppings toppingsPanel;
MainMenu menuPanel;
JButton loginBtn;
JPanel mainPanel;
CardLayout cl;
//MAIN
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PizzaSystem window = new PizzaSystem();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
//Constructor
public PizzaSystem() {
initialize();
}
//Initialize the GUI
private void initialize() {
cl = new CardLayout();
frame = new JFrame();
frame.setBounds(100, 100, 893, 527);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
mainPanel = new JPanel();
mainPanel.setBounds(10, 10, 859, 470);
frame.getContentPane().add(mainPanel);
mainPanel.setLayout(cl);
JPanel panel_2 = new JPanel();
mainPanel.add(panel_2, "test");
panel_2.setLayout(null);
JLabel lblNewLabel = new JLabel("It Worked");
lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 45));
lblNewLabel.setBounds(282, 118, 312, 103);
panel_2.add(lblNewLabel);
JPanel panel_1 = new JPanel();
loginBtn = new JButton();
loginBtn.setText("Login");
loginBtn.setBounds(175, 72, 199, 154);
loginBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showCard("menu");
}
});
panel_1.add(loginBtn);
mainPanel.add(panel_1, "loginPanel");
JPanel menuPanel = new MainMenu();
mainPanel.add(menuPanel, "menu");
showCard("loginPanel");
}
//Call card matching the key
public void showCard(String key) {
cl.show(mainPanel, key);
}
}
and one of the classes with the panel (format is messed up but should work still)
package PizzaGUI;
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
public class MainMenu extends JPanel {
public MainMenu() {
JPanel panel1 = new JPanel();
panel1.setBounds(100, 100, 893, 572);
panel1.setBackground(Color.PINK);
panel1.setLayout(null);
panel1.setVisible(true);
JLabel logoLabel = new JLabel("");
logoLabel.setBounds(10, 10, 100, 110);
panel1.add(logoLabel);
ImageIcon image1 = new ImageIcon("C:\\Users\\thera\\eclipse-workspace\\PizzaSystem\\Images\\MamaJane1.png");
logoLabel.setIcon(new ImageIcon("C:\\Users\\thera\\eclipse-workspace\\PizzaSystem\\Images\\MamaJane.png"));
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setBounds(133, 113, 548, 402);
tabbedPane.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
tabbedPane.setBackground(Color.PINK);
tabbedPane.setForeground(Color.GRAY);
tabbedPane.setFont(new Font("Tahoma", Font.PLAIN, 20));
tabbedPane.setToolTipText("");
panel1.add(tabbedPane);
JPanel panel = new JPanel();
tabbedPane.addTab("MENU", null, panel, null);
panel.setLayout(null);
//*******************************************************************************************************
//Pepperoni menu section
JLabel pizza1Image = new JLabel("IMAGE");
pizza1Image.setBounds(6, 25, 100, 100);
panel.add(pizza1Image);
ImageIcon image2 = new ImageIcon("C:\\Users\\thera\\eclipse-workspace\\PizzaSystem\\Images\\Pepperoni.jpg");
Image pizza1 = image2.getImage();
Image pepperoni = pizza1.getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH);
image2 = new ImageIcon(pepperoni);
pizza1Image.setIcon(image2);
JLabel pepperoniLabel = new JLabel("PEPPERONI");
pepperoniLabel.setHorizontalAlignment(SwingConstants.CENTER);
pepperoniLabel.setBounds(110, 25, 86, 48);
pepperoniLabel.setFont(new Font("Tahoma", Font.PLAIN, 12));
panel.add(pepperoniLabel);
JButton pepperoniOrderBtn = new JButton("ORDER");
pepperoniOrderBtn.setBounds(110, 79, 86, 47);
panel.add(pepperoniOrderBtn);
pepperoniOrderBtn.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
//Pepperoni End
JButton accountButton = new JButton("Account");
accountButton.setBounds(10, 414, 113, 39);
accountButton.setBackground(Color.WHITE);
panel.add(accountButton);
JButton checkoutButton = new JButton("Checkout");
checkoutButton.setBounds(713, 438, 138, 31);
panel.add(checkoutButton);
JButton logoutButton = new JButton("Logout");
logoutButton.setBounds(10, 463, 113, 52);
panel.add(logoutButton);
JTextArea txtrOrderInfoGoes = new JTextArea();
txtrOrderInfoGoes.setBounds(703, 10, 154, 418);
txtrOrderInfoGoes.setText("Order Info\r\nGoes Here\r\n\r\nPepperoni Pizza x1\r\n$6.50");
panel.add(txtrOrderInfoGoes);
JButton clearOrderButton = new JButton("Clear");
clearOrderButton.setBounds(723, 479, 113, 36);
panel.add(clearOrderButton);
JLabel titleLabel = new JLabel("MAMA JANE'S PIZZERIA");
titleLabel.setBounds(147, 10, 534, 65);
panel.add(titleLabel);
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.PLAIN, 50));
JLabel storeInfoLabel = new JLabel("<html>1234 Fakelane Rd <br> 10001, Faketopia, USA <br> 111-11-PIZZA <br> Mon-Fri 11AM to 10pm <br> Sat-Sun 10AM to 11pm");
storeInfoLabel.setBounds(10, 130, 113, 274);
panel.add(storeInfoLabel);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(406, 85, 2, 2);
panel.add(scrollPane);
logoutButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
}
I can't tell where I've gone wrong and I've spent roughly the last three hours trying to fix this and searching the internet for answers to no avail so thank you in advance if you can help me out.
Also I apologize in advance, I know I end up misusing the proper terminology for programming alot, I understand what things are just forget what to properly call them sometimes.
So, basically, I took out all the null layouts and "manual" layout code, as it's just going to mess with you to no end AND added add(panel1); to the end of the MainMenu constructor - as, I've said, NOTHING was added to MainMenu, so, nothing was going to get displayed.
Before you tell me that "this isn't the layout I want", understand that I understand that, but my point is, null layouts are a really bad idea, as almost the entire Swing API relies the layout managers in one way or another.
I appreciate that layout management can seem like a complex subject, but it solves some very complex problems and it's worth taking the time to learn them. Remember, you're not stuck to a single layout manager, you can use component components to adjust individual containers to their individual needs.
You can take a look at:
Layout using Java Swing
Which Layout Manager to use?
How I can do swing complex layout Java
How to use Java Swing layout manager to make this GUI?
*Which java swing layout should I use
to some ideas how you might approach designing a complex UI.
You should also take a look at Laying Out Components Within a Container
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
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.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
public class PizzaSystem {
private JFrame frame;
// Toppings toppingsPanel;
MainMenu menuPanel;
JButton loginBtn;
JPanel mainPanel;
CardLayout cl;
//MAIN
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PizzaSystem window = new PizzaSystem();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
//Constructor
public PizzaSystem() {
initialize();
}
//Initialize the GUI
private void initialize() {
cl = new CardLayout();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel = new JPanel(cl);
frame.getContentPane().add(mainPanel);
JPanel panel_1 = new JPanel(new GridBagLayout());
loginBtn = new JButton();
loginBtn.setText("Login");
loginBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showCard("menu");
}
});
panel_1.add(loginBtn);
mainPanel.add(panel_1, "loginPanel");
JPanel menuPanel = new MainMenu();
mainPanel.add(menuPanel, "menu");
frame.pack();
showCard("loginPanel");
}
//Call card matching the key
public void showCard(String key) {
cl.show(mainPanel, key);
}
public class MainMenu extends JPanel {
public MainMenu() {
JPanel panel1 = new JPanel(new BorderLayout());
JLabel logoLabel = new JLabel("Logo");
panel1.add(logoLabel, BorderLayout.NORTH);
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setToolTipText("");
panel1.add(tabbedPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
tabbedPane.addTab("MENU", null, panel, null);
//*******************************************************************************************************
//Pepperoni menu section
JLabel pizza1Image = new JLabel("IMAGE");
panel.add(pizza1Image);
JLabel pepperoniLabel = new JLabel("PEPPERONI");
pepperoniLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(pepperoniLabel);
JButton pepperoniOrderBtn = new JButton("ORDER");
pepperoniOrderBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
//Pepperoni End
JButton accountButton = new JButton("Account");
panel.add(accountButton);
JButton checkoutButton = new JButton("Checkout");
panel.add(checkoutButton);
JButton logoutButton = new JButton("Logout");
panel.add(logoutButton);
JTextArea txtrOrderInfoGoes = new JTextArea(10, 20);
txtrOrderInfoGoes.setText("Order Info\r\nGoes Here\r\n\r\nPepperoni Pizza x1\r\n$6.50");
panel.add(txtrOrderInfoGoes);
JButton clearOrderButton = new JButton("Clear");
panel.add(clearOrderButton);
JLabel titleLabel = new JLabel("MAMA JANE'S PIZZERIA");
panel.add(titleLabel);
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.PLAIN, 50));
JLabel storeInfoLabel = new JLabel("<html>1234 Fakelane Rd <br> 10001, Faketopia, USA <br> 111-11-PIZZA <br> Mon-Fri 11AM to 10pm <br> Sat-Sun 10AM to 11pm");
panel.add(storeInfoLabel);
JScrollPane scrollPane = new JScrollPane();
panel.add(scrollPane);
logoutButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
add(panel1);
}
}
}

How do I stop JFrame/JPanel from auto-formatting the distances between my components?

So I'm writing a program which utilizes a GUI. The GUI is built from a JFrame and a JPanel in Java. I have a JTextArea() and a JButton() that appears beside the JTextArea on the left. I also have an image which I imported locally using the method call below ("f" is the variable name of my JFrame):
f.setIconImage(ImageIO.read(new File("image.png")));
I don't mind allowing the users to resize the JFrame but what I dislike is that JFrame automatically reformats the components on my JFrame - specifically the distance between my image and the JTextArea(). I'd like, if possible, to keep the distance between my image and the JTextArea the same regardless of the size the user resizes the JFrame to. Here's the rest of my code if that helps:
public class GUI {
private JFrame f;
private JPanel p;
private JButton b1;
private JLabel lab;
private JTextArea tf;
private static final String FileName = "schedule.txt";
private static final String FileName2 = "schedule2.txt";
public void show()
{
f = new JFrame("Scheduler");
f.setSize(600, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new JPanel();
//p.setPreferredSize(new Dimension(200, 400));
b1 = new JButton("Run");
p.add(b1);
f.add(p);
f.add(p, BorderLayout.SOUTH);
f.add(new JLabel(new ImageIcon("image.png")));
try {
f.setIconImage(ImageIO.read(new File("image.png")));
} catch(Exception z){
System.out.println("Trouble reading file");
}
tf = new JTextArea();
tf.setPreferredSize(new Dimension(300, 200));
p.add(tf);
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String text = tf.getText();
try {
FileWriter fw = new FileWriter(FileName);
fw.write(text);
fw.close();
parseInfo();
}
catch(Exception ex)
{
}
}
});
f.setVisible(true);
}
There are any number of ways you "might" achieve this, but the basic answer is, you need to choose one or more layout managers which better meets your needs.
For example, using a GridBagLayout, you can do something like...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.LineBorder;
public class JavaApplication1 {
public static void main(String[] args) {
new JavaApplication1();
}
public JavaApplication1() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(8, 8, 8, 8);
JLabel label = new JLabel("Image placeholder") {
// This is done only for demonstration purposes
#Override
public Dimension getPreferredSize() {
return new Dimension(128, 128);
}
};
label.setBorder(new LineBorder(Color.DARK_GRAY));
add(label, gbc);
gbc.gridy++;
gbc.fill = GridBagConstraints.BOTH;
// This will cause the text area to occupy all the avalilable free space
//gbc.weightx = 1;
//gbc.weighty = 1;
JTextArea ta = new JTextArea(10, 20);
add(new JScrollPane(ta), gbc);
JButton btn = new JButton("Run");
gbc.gridy++;
// Reset the constraints
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(btn, gbc);
}
}
}
Take a look at Laying Out Components Within a Container for more details and ideas
Recommendations...
There are a few things in your code that are, "off", but this...
tf = new JTextArea();
tf.setPreferredSize(new Dimension(300, 200));
p.add(tf);
is probably the most striking.
Generally speaking, JTextArea will benefit from been wrapped in a JScrollPane. Also, due to the inconsistencies in how text is rendered across multiple platforms, you should avoid using setPreferredSize (in fact, you should avoid using it in general) and instead rely in the rows, columns constructor, which will make calculations based on the current font and graphics properties.

How can I attach the progress bar to when the JFrame Opens?

I want to attached the progress bar to the Frame and not the test start button that I have currently. The progress bar works but I want it run when the window is opened for the time being and then I can attach it to whatever I want later on.
Code:
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.JProgressBar;
import javax.swing.JButton;
public class ProgressBarWindow extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ProgressBarWindow frame = new ProgressBarWindow();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ProgressBarWindow() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) { }
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 183);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JProgressBar progressBar = new JProgressBar();
progressBar.setBounds(22, 77, 386, 27);
contentPane.add(progressBar);
JButton btnNewButton = new JButton("Cancel");
btnNewButton.setBounds(319, 111, 89, 23);
btnNewButton.addMouseListener(new myMouseListener2());
contentPane.add(btnNewButton);
JButton btnStart = new JButton("Start");
btnStart.addActionListener(new btnDoAction(progressBar));
btnStart.setBounds(220, 111, 89, 23);
contentPane.add(btnStart);
}
}
class myClose implements MouseListener {
myClose() { }
#Override
public void mouseClicked(MouseEvent e) {
final Component source = e.getComponent();
final JFrame frame = (JFrame) SwingUtilities.getRoot(source);
frame.dispose();
}
#Override
public void mousePressed(MouseEvent e) {
final Component source = e.getComponent();
final JFrame frame = (JFrame) SwingUtilities.getRoot(source);
frame.dispose();
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
class btnDoAction implements ActionListener{
JProgressBar temp = new JProgressBar();
btnDoAction(JProgressBar p) {
this.temp = p;
}
public void actionPerformed (ActionEvent e){
new Thread(new thread1(temp)).start(); //Start the thread
}
}
class thread1 implements Runnable{
JProgressBar pBar = new JProgressBar();
thread1(JProgressBar u) {
this.pBar = u;
}
public void run(){
for (int i=0; i<=100; i++){ //Progressively increment variable i
pBar.setValue(i); //Set value
pBar.repaint(); //Refresh graphics
try{Thread.sleep(50);} //Sleep 50 milliseconds
catch (InterruptedException err){}
}
}
}
If I understand correctly, instead of using a JFrame as you base component, extend your class from a JPanel, this way you can add it to anything you want.
You could then provide setter and getter methods to adjust the progress bar, but I'd do this via some kind of interface contract .
Don't use null layouts. You don't control aspects like fonts, font metrics, rendering pipelines and other properties which effect the amount of space components need in order to be rendered properly across multiple systems (even those running the same OS)
Don't use MouseListeners on buttons, use ActionListeners instead. To takes into account when the use clicks on the button and presses space/Zener
Don't update the UI from any thread other then the a Event Dispatching Thread. See Concurrency in Swing for more details. Consider using a SwingWorker instead, it has functionality to sync the background thread with the EDT and in built progress support
Updated
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class LayoutExample {
public static void main(String[] args) {
new LayoutExample();
}
public LayoutExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ProgressPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ProgressPane extends JPanel {
private JProgressBar pb;
private JButton start;
private JButton cancel;
public ProgressPane() {
pb = new JProgressBar();
start = new JButton("Start");
cancel = new JButton("Cacnel");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(50, 10, 5, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.gridwidth = 2;
add(pb, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = new Insets(0, 0, 0, 5);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 1;
gbc.gridwidth = 1;
gbc.anchor = GridBagConstraints.EAST;
add(start, gbc);
gbc.weightx = 0;
gbc.gridx = 1;
gbc.insets = new Insets(0, 0, 0, 10);
gbc.anchor = GridBagConstraints.WEST;
add(cancel, gbc);
}
}
}

More than one JFrame

I currently have two frames, when you run the application the first JFrame that shows is a login, it has two input fields and a button. When the user logs in and is verified, I would like to close the frame and start up the second one.
So, the only thing I can think of doing is doing setVisible(false) for the login frame and setVisible(true) for the Main frame.
Is there a better way to do this, or is that the only way?
Personnally, I would start up your second JFrame immediately and replace your first frame with a modal JDialog which would be owned by the JFrame.
See also this answer to The Use of Multiple JFrames, Good/Bad Practice?
Here is a basic demo of what I suggest:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLogin {
private JFrame frame;
private boolean authenticated;
private JTextField login;
private JPasswordField password;
protected void initUI() {
frame = new JFrame(TestLogin.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setVisible(true);
}
protected void showLoginDialog() {
authenticated = false;
final JDialog dialog = new JDialog(frame, "Please provide your credentials");
dialog.setModal(true);
JPanel panel = new JPanel(new GridBagLayout());
JPanel buttonPanel = new JPanel();
login = new JTextField(40);
password = new JPasswordField(20);
JLabel loginLabel = new JLabel("Login:");
JLabel passwordLabel = new JLabel("Password:");
JButton ok = new JButton("OK");
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Here perform authentication and set authentication flag to appropriate value
authenticated = true;
if (authenticated) {
setUpFrame();
dialog.dispose();
}
}
});
JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
dialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
if (!authenticated) {
System.exit(0);
}
}
});
dialog.getRootPane().setDefaultButton(ok);
buttonPanel.add(ok);
buttonPanel.add(cancel);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(loginLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1.0;
panel.add(login, gbc);
gbc.gridwidth = 1;
gbc.weightx = 0;
panel.add(passwordLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1.0;
panel.add(password, gbc);
panel.add(buttonPanel, gbc);
dialog.add(panel);
dialog.pack();
dialog.setLocationRelativeTo(frame);
while (!authenticated) {
dialog.setVisible(true);
}
}
protected void setUpFrame() {
frame.add(new JLabel("Successfully authenticated"));
frame.revalidate();
frame.repaint();
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestLogin testLogin = new TestLogin();
testLogin.initUI();
testLogin.showLoginDialog();
}
});
}
}
There are several ways to do that.
E.g. you could reuse your 1st JFrame. Therefore remove the components you got on your 1st frame, add the ones for the 2nd and then repaint() the frame.
But I wouldn't consider that as good practice.
As Andrew Thompson suggested, you could also use a CardLayout to just initialize one JFrame, show your login-card and then switch to the fully initialized 2nd full-application card. This way you will get rid of those repaints.
You could also show your 2nd frame (your application first) and then use a modal JDialog to the let user log in.

Categories