I am unable to change the colour of my frame in Java code below. I know the code to change it would be frame.getContentPane().setBackground(Color.gray); However, this is not working for me, I am not sure what is the reason behind this, but if you are able to solve the problem do let me know, thank you.
public class UserLoginPage implements ActionListener {
//Put all JLabels,Frames and buttons here etc
JPanel panel = new JPanel();
JFrame frame = new JFrame();
JLabel userLabel = new JLabel("Username");
JLabel passwordLabel = new JLabel("Password");
JTextField userText = new JTextField();
JTextField passwordText = new JTextField();
JButton loginButton = new JButton("Login");
//Label for successful login
JLabel success = new JLabel();
//Default Constructor to add the frames and panels etc
public UserLoginPage(){
panel.setLayout(null);
userLabel.setBounds(10,20,80,25);
panel.add(userLabel);
passwordLabel.setBounds(10,50,80,25);
panel.add(passwordLabel);
userText.setBounds(100,20,165,25);
panel.add(userText);
passwordText.setBounds(100,50,165,25);
panel.add(passwordText);
loginButton.setBounds(10,80,80,25);
loginButton.addActionListener(this);
panel.add(loginButton);
success.setBounds(10,110,300,25);
panel.add(success);
//success.setText();
frame.setSize(500,500);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.gray);
frame.setVisible(true);
frame.add(panel);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new UserLoginPage();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
String user = userText.getText();
String password = passwordText.getText();
System.out.println(user + ", " + password);
if(user.equals("Jackson") && password.equals("1234")){
JOptionPane.showMessageDialog(frame,"Login successful");
}
else{
JOptionPane.showMessageDialog(frame,"Invalid password or username");
}
}
}
You're adding panel, a JPanel to your JFrame, and since JFrame's contentPane uses a BorderLayout, this JPanel (which is opaque), will completely cover the contentPane, preventing visualization of the contentPane's background.
Solution:
Either make the panel not-opaque via panel.setOpaque(false); so that now its container's colors or images will show through
or leave it default opaque give it and not the contentPane the background color of choice.
Unrelated issue is here:
panel.setLayout(null)
You really don't want to be doing this for many reasons, including because this will make your GUI work well / look nice on only one platform. It also makes it very hard to upgrade and enhance the GUI later.
For example, and incorporating some of Andrew Thompson's suggestions, here is an example login GUI that is geared towards creating a JPanel, one that in this example is placed into a modal JDialog (similar to a JOptionPane but with more flexibility) and displayed. The code uses GridBagLayout along with GridBagConstraints when adding components to place them where I want them to be in a pleasing way that works on all platforms, and that allows ease and flexibility should I want to add more components:
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class UserLoginPanel extends JPanel {
private static final Color BACKGROUND = new Color(200, 200, 200);
private JTextField userText = new JTextField(15);
private JPasswordField passwordText = new JPasswordField(15);
LoginAction loginAction = new LoginAction(this, "Login", KeyEvent.VK_L);
JButton loginButton = new JButton(loginAction);
public UserLoginPanel() {
super(new GridBagLayout());
setBackground(BACKGROUND);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
int insetGap = 4;
gbc.insets = new Insets(insetGap, insetGap, insetGap, insetGap);
add(new JLabel("User Name:"), gbc);
gbc.gridx = 1;
add(userText, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(new JLabel("Password"), gbc);
gbc.gridx = 1;
add(passwordText, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 2;
add(loginButton, gbc);
insetGap = 8;
setBorder(BorderFactory.createEmptyBorder(insetGap, insetGap, insetGap, insetGap));
}
public String getUserName() {
return userText.getText();
}
public char[] getPassword() {
return passwordText.getPassword();
}
public static void main(String[] args) {
UserLoginPanel loginPanel = new UserLoginPanel();
JDialog dialog = new JDialog(null, "User Login", ModalityType.APPLICATION_MODAL);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.add(loginPanel);
dialog.pack();
dialog.setLocationByPlatform(true);
dialog.setVisible(true);
}
}
#SuppressWarnings("serial")
class LoginAction extends AbstractAction {
private UserLoginPanel loginPanel;
public LoginAction(UserLoginPanel loginPanel, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, KeyEvent.VK_L);
this.loginPanel = loginPanel;
}
#Override
public void actionPerformed(ActionEvent e) {
String userName = loginPanel.getUserName();
char[] password = loginPanel.getPassword();
System.out.println("User Name: " + userName);
System.out.println("Password: " + new String(password));
Component source = (Component) e.getSource();
if (source != null) {
Window window = SwingUtilities.getWindowAncestor(source);
if (window != null) {
window.dispose();
}
}
}
}
Related
Recently I'm writing a mail system client using Java (I chose swing to write the GUI and use IDEA to hardcode my GUI). In the Compose module, I want to show or hide the textfield for CC and Bcc when I click the corresponding buttons.
So I googled and browsed the following questions and doc on the web:
How to make JPanel scrollable in Java?
How to make JPanel scrollable?
Scrolling a JPanel
Doc: JScrollPane
Finally, I chose the JScrollPane to implement it.
My simplified sample code is as follows (the original code is tedious):
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Demo extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JLabel lbl1;
private JTextField txf1;
private JLabel lbl2;
private JTextField txf2;
// container for lbl2 and txf2, which should be able to be shown or hidden
private JPanel pnlContainer2;
private JLabel lbl3;
private JTextField txf3;
// container for lbl3 and txf3
private JPanel pnlContainer3;
private JButton btnShow;
// the container I want to move when I click btnShow
private JPanel pnlBody;
// the panel to hold my "cards"
// In this example, I include it just to show what controls are on my interface.
private JPanel pnlContent;
private JPanel pnlContainer;
// here, I want to use JScrollPane to make my pnlContainer scrollable
// to adapt to my interface
private JScrollPane scrollPane;
public Demo() {
init();
}
private void init() {
pnlContainer = new JPanel(new CardLayout(), true);
pnlContainer.setBounds(0, 0, 200, 180);
pnlContent = new JPanel(null, true);
pnlContent.setBounds(0, 0, 200, 180 + 50);
scrollPane = new JScrollPane(pnlContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(0, 0, 200, 180);
pnlContainer.add(scrollPane);
pnlBody = new JPanel(null, true);
lbl1 = new JLabel("lbl1");
lbl1.setBounds(10, 20, 40, 30);
txf1 = new JTextField();
txf1.setBounds(60, 20, 120, 30);
pnlContent.add(lbl1);
pnlContent.add(txf1);
pnlContainer2 = new JPanel(null, true);
pnlContainer2.setBounds(0, 70, 180, 30);
lbl2 = new JLabel("lbl2");
lbl2.setBounds(10, 0, 40, 30);
txf2 = new JTextField();
txf2.setBounds(60, 0, 120, 30);
pnlContainer2.add(lbl2);
pnlContainer2.add(txf2);
pnlContainer2.setVisible(false);
pnlContent.add(pnlContainer2);
pnlBody = new JPanel(null, true);
pnlBody.setBounds(0, 70, 180, 90);
pnlContainer3 = new JPanel(null, true);
pnlContainer3.setBounds(0, 0, 180, 30);
pnlBody.add(pnlContainer3);
lbl3 = new JLabel("lbl3");
lbl3.setBounds(10, 0, 40, 30);
txf3 = new JTextField();
txf3.setBounds(60, 0, 120, 30);
pnlContainer3.add(lbl3);
pnlContainer3.add(txf3);
btnShow = new JButton("show");
btnShow.setBounds(60, 50, 80, 30);
btnShow.addActionListener(this);
pnlBody.add(btnShow);
pnlContent.add(pnlBody);
this.add(pnlContainer);
this.setLayout(null);
this.setTitle("Demo");
this.setSize(200, 200);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setResizable(false);
// ImageIcon icon = new ImageIcon("E:\\Javarepo\\Hmail\\src\\main\\resources\\assets\\hmail.png");
// this.setIconImage(icon.getImage());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Object src = e.getSource();
if (src instanceof JButton) {
JButton btn = (JButton) src;
boolean showSelected = false;
String altText;
if (btn == btnShow) {
showSelected = btnShow.getText() == "show";
altText = showSelected ? "hide" : "show";
btnShow.setText(altText);
}
relayout(showSelected);
}
}
private void relayout(boolean showSelected) {
int x = pnlBody.getX();
int y = pnlBody.getY();
if (showSelected) {
pnlContainer2.setVisible(true);
pnlBody.setBounds(x, y + 50, 180, 90);
} else {
pnlContainer2.setVisible(false);
pnlBody.setBounds(x, y - 50, 180, 90);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Demo());
}
}
However, no matter which JPanel I apply JScrollPane to, I cannot make my interface adaptive to the hide and show of my JContainer2.
How can I modify it, or what control to use to replace JScrollPane? Any suggestions will be welcome.
And here is my platform information:
java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
OS: win10 1909
arch: amd64
I rewrote your code. Explanations appear after it.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
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.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;
public class Demo2 implements ActionListener, Runnable {
private static final String HIDE = "HIDE";
private static final String SHOW = "SHOW";
private JButton button;
private JLabel lbl2;
private JFrame frame;
private JTextField txf2;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent event) {
boolean visible;
String text;
String actionCommand = event.getActionCommand();
switch (actionCommand) {
case HIDE:
text = SHOW;
visible = false;
break;
case SHOW:
text = HIDE;
visible = true;
break;
default:
text = "???";
visible = false;
}
button.setText(text);
lbl2.setVisible(visible);
txf2.setVisible(visible);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
button = new JButton(SHOW);
button.addActionListener(this);
buttonsPanel.add(button);
return buttonsPanel;
}
private JScrollPane createForm() {
JPanel form = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
JLabel lbl1 = new JLabel("lbl1");
form.add(lbl1, gbc);
gbc.gridx = 1;
JTextField txf1 = new JTextField(6);
form.add(txf1, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
lbl2 = new JLabel("lbl2");
lbl2.setVisible(false);
form.add(lbl2, gbc);
gbc.gridx = 1;
txf2 = new JTextField(6);
txf2.setVisible(false);
form.add(txf2, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
JLabel lbl3 = new JLabel("lbl3");
form.add(lbl3, gbc);
gbc.gridx = 1;
JTextField txf3 = new JTextField(6);
form.add(txf3, gbc);
return new JScrollPane(form,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
private void showGui() {
frame = new JFrame("Demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(createForm(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
/**
* Start here.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Demo2());
}
}
You should always try to use a layout manager. The code above uses GridBagLayout but there are several other layout managers that are good at handling forms, including GroupLayout and SpringLayout as well as third party layout managers like MiG Layout and FormLayout.
In order to "show" and "hide" the middle row in your form, simply set the visible property to true or false. If the text of the button is SHOW, then when the user clicks on it, I change the button text to HIDE and make lbl2 and txf2 both visible. If the button text is HIDE, then when the user clicks the button I change the text to SHOW and make lbl2 and txf2 not visible.
Because I use a layout manager, it handles resizing the JPanel whenever the contents of the JPanel are changed. When you don't use a layout manager, then you have to write code that handles the resizing and of-course your code does not, hence your problem.
I want to make list of JButtons (with fixed dimensions, one beneath another) inside JScrollPane, using Swing. My idea was to make JPanel with GridBagLayout and add buttons in their suiting rows, and then create JScrollPane with that JPanel. That looks fine when number of buttons is large, but when the number of buttons is 2 or 3, I can't manage to align buttons one right below the other.
Also later I will add option to add new button (thus the + sign).
Works fine with 10 buttons
I get this empty space between button 0 and button 1 when it's just 2 buttons (this is the problem)
The code (creates upper east panel)
private JPanel createLayerPanel() {
JPanel layerPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// Label ------------------------------------------------
JLabel layersLabel = new JLabel("Buttons");
layersLabel.setHorizontalAlignment(SwingConstants.CENTER);
layersLabel.setFont(DEFAULT_FONT);
//layersLabel.setBorder(new LineBorder(Color.red, 3));
layersLabel.setBackground(new Color(0x22222));
layersLabel.setForeground(new Color(0xFFFFFF));
layersLabel.setOpaque(true);
c.gridx = c.gridy = 0;
c.ipadx = 180;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
layerPanel.add(layersLabel, c);
// Button ------------------------------------------------
JButton newLayerBtn = new JButton("+");
newLayerBtn.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 18));
newLayerBtn.setBackground(new Color(0x222222));
newLayerBtn.setForeground(Color.white);
newLayerBtn.setFocusable(false);
c.gridx = 1;
c.gridy = 0;
c.ipadx = 0;
c.weightx = 0;
layerPanel.add(newLayerBtn, c);
// ScrollPane ------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
JPanel layerListPanel = new JPanel(new GridBagLayout());
layerListPanel.setBackground(Color.BLACK);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1;
gbc.ipady = 40;
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.NORTH;
for (gbc.gridy = 0; gbc.gridy < 10; gbc.gridy++) {
JButton btn = new JButton("Button " + gbc.gridy);
layerListPanel.add(btn, gbc);
}
JScrollPane js = new JScrollPane(layerListPanel);
js.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// ...
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 2;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
layerPanel.add(js, c);
return layerPanel;
}
Do you absolutely need a GridBagLayout?
I just made a demo using a simple Box.
And please have a look at How to write an SSCCE.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class YY extends JFrame {
static String[] args;
public YY() {
setSize(160, 200);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
int icnt= args.length==0 ? 5 : Integer.parseInt(args[0]);
Box box= Box.createVerticalBox();
for (int i=1; i<=icnt; i++) {
JButton btn= new JButton("Button "+i);
btn.setMaximumSize(new Dimension(150, 30));
box.add(btn);
}
JScrollPane scroll= new JScrollPane(box);
scroll.setPreferredSize(new Dimension(150, 100));
add(scroll);
setVisible(true);
}
public static void main(String... args) {
YY.args= args;
EventQueue.invokeLater(YY::new);
}
}
The below code initially displays a JFrame that contains a single JButton that displays the text Add. Each time you click the button a new JButton appears above it. The text on each newly created button is a three digit number with leading zeros that is incremented each time the Add button is clicked. And whenever a new button is added, the JFrame increases in height in order to display the newly added button.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
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.WindowConstants;
public class GridBttn implements ActionListener, Runnable {
private int counter;
private JFrame frame;
private JPanel gridPanel;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent event) {
addButtonToGridPanel();
}
private void addButtonToGridPanel() {
JButton button = new JButton(String.format("%03d", counter++));
gridPanel.add(button);
frame.pack();
}
private JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton("Add"));
return buttonsPanel;
}
private JPanel createGridPanel() {
gridPanel = new JPanel(new GridLayout(0, 1));
return gridPanel;
}
private void showGui() {
frame = new JFrame("Grid");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createGridPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new GridBttn());
}
}
Note the parameters to GridLayout constructor. Zero rows and one column. This means that whenever a Component is added to the JPanel it will be placed directly beneath the last Component added. In other words all the components added will appear in a single column. Also note that I call method pack() (of class JFrame) after adding a new button. This causes the JFrame to recalculate its size in order to display all the buttons.
EDIT
Due to OP's comment slightly modified above code so as to be more suitable to his requirements.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;
public class GridBttn implements ActionListener, Runnable {
private int counter;
private JFrame frame;
private JPanel gridPanel;
private JPanel gridPanel2;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent event) {
addButtonToGridPanel();
}
private void addButtonToGridPanel() {
JButton button = new JButton(String.format("%03d", counter++));
gridPanel2.add(button);
frame.pack();
}
private JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton("Add"));
return buttonsPanel;
}
private JPanel createMainPanel() {
gridPanel = new JPanel();
gridPanel.setPreferredSize(new Dimension(400, 300));
return gridPanel;
}
private JScrollPane createScrollPane() {
gridPanel2 = new JPanel();
BoxLayout layout = new BoxLayout(gridPanel2, BoxLayout.PAGE_AXIS);
gridPanel2.setLayout(layout);
JScrollPane scrollPane = new JScrollPane(gridPanel2,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(70, 0));
return scrollPane;
}
private void showGui() {
frame = new JFrame("Grid");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createScrollPane(), BorderLayout.LINE_END);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new GridBttn());
}
}
For some reason my borders aren't showing for my panels and i am unsure why, is there something i'm missing?
I have a main class which runs the frame class as well as other classes separate to the GUI
This is the code from my frame class:
import javax.swing.*;
import java.awt.*;
public class Frame
{
public static int xsize;
public static int ysize;
public static void main()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new MainFrame("Warlock of Firetop Mountain");
//Implementing Toolkit to allow computer to get dimensions of screen and assign them to two int values
Toolkit tk = Toolkit.getDefaultToolkit();
Frame.xsize = (int) tk.getScreenSize().getWidth();
Frame.ysize = (int) tk.getScreenSize().getHeight();
frame.setTitle("Warlock of Firetop Mountain");
frame.setSize(new Dimension(xsize, ysize));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
The frame.java takes its panels from MainFrame.java:
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame
{
private Panel1 storyPanel;
private Panel2 statsPanel;
private Panel3 commandsPanel;
public MainFrame(String title)
{
super(title);
// Setting Layout
setLayout(new BorderLayout());
storyPanel = new Panel1();
statsPanel = new Panel2();
commandsPanel = new Panel3();
Container p = getContentPane();
p.add(storyPanel, BorderLayout.WEST);
p.add(statsPanel, BorderLayout.EAST);
p.add(commandsPanel, BorderLayout.SOUTH);
}
}
This calls up my three panels which look like this:
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Dimension;
import java.awt.Color;
public class Panel1 extends JPanel
{
public Panel1()
{
//Set size of Panel1
int xsizeP1 = (Frame.xsize / 2);
int ysizeP1 = (Frame.ysize / 3 * 2);
setPreferredSize(new Dimension(xsizeP1, ysizeP1));
setBorder(BorderFactory.createLineBorder(Color.black));
}
}
when the code runs the window launches as full screen but no borders or possibly panels are visible.
Thanks for any help, sorry if my questions are tedious, i'm relatively new to programming.
This is roughly what i want my panels to look like, eventually ill add in components to the panel and use GridBagConstraints to control the formatting
// this creates the JPanels and sets their preferred sizes
JFrame frame = new MainFrame("Warlock of Firetop Mountain");
//this sets your size static contents -- after the above's been done!
Toolkit tk = Toolkit.getDefaultToolkit();
Frame.xsize = (int) tk.getScreenSize().getWidth();
Frame.ysize = (int) tk.getScreenSize().getHeight();
You're setting preferred sizes of all your JPanels to 0, 0, and so you're not seeing any borders. Your sizing is being created after you've created your JPanels, and this method of sizing looks dangerous to me.
OK, thanks for posting an image of the desired GUI. My recommendations are:
First and foremost, don't try setting sizes as you're doing.
Instead, let the components and their layout managers size themselves.
Nest JPanels, each using its own layout manager to allow you to simply create complex GUI's.
When displaying images / ImageIcons, let them set the sizes of things as well.
If your GUI starts up with no icons displaying, consider creating a blank ImageIcon with a blank image of the right size as a placeholder icon.
For example, something like this:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
#SuppressWarnings("serial")
public class TomGuiPanel extends JPanel {
// rows and cols for jtextarea
private static final int CURRENT_AREA_ROWS = 20;
private static final int CURRENT_AREA_COLS = 40;
// columns for command jtextfied
private static final int COMMANDS_FIELD_COLS = 50;
// size of GUI component gaps
private static final int EB_GAP = 3;
private static final int NUMBER_OF_OPTIONS = 5;
// number if ImageIcons displayed within the user image char JList
private static final int CHAR_IMG_VISIBLE_ROWS = 5;
// a guess of the width of the largest image icon in the JList
// You'd use a different number
private static final int USER_IMG_CHAR_IMG_WIDTH = 70;
private JTextArea currentTextArea = new JTextArea(CURRENT_AREA_ROWS, CURRENT_AREA_COLS);
private JTextField commandsField = new JTextField(COMMANDS_FIELD_COLS);
private EnterAction enterAction = new EnterAction("Enter");
private DefaultListModel<Icon> charImgListModel = new DefaultListModel<>();
private JList<Icon> charImgList = new JList<>(charImgListModel);
public TomGuiPanel() {
JPanel topBtnPanel = new JPanel(new GridLayout(1, 0, EB_GAP, EB_GAP));
String[] btnTexts = { "Inventory", "Options", "Save", "Load" };
for (String txt : btnTexts) {
topBtnPanel.add(new JButton(txt));
}
JPanel characteristicsPanel = new JPanel(new GridBagLayout());
addCharacteristics(characteristicsPanel, "HP", 20, 0);
addCharacteristics(characteristicsPanel, "Attack", 12, 1);
addCharacteristics(characteristicsPanel, "Defence", 8, 2);
addCharacteristics(characteristicsPanel, "Agility", 9, 3);
addCharacteristics(characteristicsPanel, "Luck", 2, 4);
JScrollPane imgListPane = new JScrollPane(charImgList);
imgListPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
charImgList.setVisibleRowCount(CHAR_IMG_VISIBLE_ROWS);
charImgList.setPrototypeCellValue(createProtoType());
JPanel rightPanel = new JPanel(new BorderLayout(EB_GAP, EB_GAP));
rightPanel.add(topBtnPanel, BorderLayout.PAGE_START);
rightPanel.add(imgListPane, BorderLayout.CENTER);
rightPanel.add(characteristicsPanel, BorderLayout.LINE_END);
JPanel optionsPanel = new JPanel(new GridLayout(1, 0));
for (int i = 0; i < NUMBER_OF_OPTIONS; i++) {
String text = "Option " + (i + 1);
optionsPanel.add(new JCheckBox(text));
}
currentTextArea.setWrapStyleWord(true);
currentTextArea.setLineWrap(true);
currentTextArea.setFocusable(false);
JScrollPane taScrollPane = new JScrollPane(currentTextArea);
taScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(taScrollPane, BorderLayout.CENTER);
centerPanel.add(rightPanel, BorderLayout.LINE_END);
centerPanel.add(optionsPanel, BorderLayout.PAGE_END);
JPanel commandsPanel = new JPanel();
commandsPanel.setLayout(new BoxLayout(commandsPanel, BoxLayout.LINE_AXIS));
commandsPanel.add(commandsField);
commandsPanel.add(Box.createHorizontalStrut(EB_GAP));
commandsPanel.add(new JButton(enterAction));
commandsPanel.add(Box.createHorizontalStrut(EB_GAP));
commandsPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
commandsField.setAction(enterAction); // use same action for button and
// text field
setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
setLayout(new BorderLayout(EB_GAP, EB_GAP));
add(centerPanel, BorderLayout.CENTER);
add(commandsPanel, BorderLayout.PAGE_END);
}
private void addCharacteristics(JPanel cPanel, String text, int value, int row) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = row;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.WEST;
cPanel.add(new JLabel(text), gbc);
gbc.insets.left = 20;
gbc.anchor = GridBagConstraints.EAST;
gbc.gridx = 1;
cPanel.add(new JLabel(String.valueOf(value)), gbc);
}
private Icon createProtoType() {
int w = USER_IMG_CHAR_IMG_WIDTH;
int h = w;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Icon icon = new ImageIcon(img);
return icon;
}
private class EnterAction extends AbstractAction {
public EnterAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
String text = commandsField.getText();
currentTextArea.append(text + "\n");
commandsField.selectAll();
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component source = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(source);
win.dispose();
}
}
private static void createAndShowGUI() {
TomGuiPanel mainPanel = new TomGuiPanel();
JFrame frame = new JFrame("Tom's GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Would create this realizable GUI:
Note that the GUI is roughly made, has no functionality other than the enter and exit buttons.
I have an ItemListener that looks like this:
private class Listener implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
calculate();
}
}
At the bottom of my calculate() method, I set these labels like this:
subtotalLbl.setText("\t\t\t\t\t\t\t\tSubtotal:\t\t\t\t\t\t\t\t\t " + String.valueOf(determinedSubTotal + priceIncrease) + "\t\t\t\t\t\t\t\t\t");
taxLbl.setText("\t\t\t\t\t\t\t\tTax:\t\t\t\t\t\t\t\t\t " + String.valueOf(determinedTax + priceIncrease) + "\t\t\t\t\t\t\t\t\t");
totalLbl.setText("\t\t\t\t\t\t\tTotal:\t\t\t\t\t\t\t\t\t " + String.valueOf(determinedTotal + priceIncrease) + "\t\t\t\t\t\t\t\t\t");
Then I have an ActionListener that uses the text from the totalLbl for parseDouble
private class BtnClicked implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input = totalLbl.getText().trim();
Double parsedString = Double.parseDouble(input) * 0.20;
Object src = e.getSource();
if(src == submit)
{
JOptionPane.showMessageDialog(null,"Thank you for your order - the tip will be " + fmt.format(parsedString), "Thank you" , JOptionPane.INFORMATION_MESSAGE);
}
else if(src == cancel)
{
JOptionPane.showMessageDialog(null,"Order was canceled" ,"Order Canceled" , JOptionPane.INFORMATION_MESSAGE);
}
}
Obviously the program is crashing at the line inside of the BtnClicked's actionPerformed method where parseDouble(input) is at, because the totalLbl JLabel has "Total:" in it.. where else would I set this or how would I work around this? The "Total:" is required. (can't use split() )
Here's a screenshot of what the entire JFrame looks like, program crashes when clicking the submit button:
Create two JLables, one which says Total: the other which actually holds the total value.
So your total calculation would look more like...
totalLblText.setText("Total:");
totalLbl.setText(String.valueOf(determinedTotal + priceIncrease));
Then you won't need to care.
You should make better use of your layout managers in order to support the formatting your trying to achieve rather than using formatting characters like \t, these will always end up in a mess
Updated with layout example
This simple example demonstrates how you might use a layout managers (and a technique known as compound layouts) and relieve the need to try and use a single label for displaying more information then it should...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLayout {
public static void main(String[] args) {
new TestLayout();
}
public TestLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextField numberOfPizzas;
private JCheckBox pepperoni;
private JCheckBox sausage;
private JCheckBox peppers;
private JCheckBox onions;
private JCheckBox mushrooms;
private JCheckBox extracheese;
private JLabel lblSubTotal;
private JLabel lblTax;
private JLabel lblTotal;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
JPanel header = new JPanel();
JPanel extras = new JPanel(new GridBagLayout());
JPanel totals = new JPanel(new GridBagLayout());
add(header, gbc);
gbc.gridy++;
add(extras, gbc);
gbc.gridy++;
add(totals, gbc);
numberOfPizzas = new JTextField(5);
header.add(new JLabel("Number of pizzas"));
header.add(numberOfPizzas);
gbc = new GridBagConstraints();
pepperoni = new JCheckBox("Pepperoni");
sausage = new JCheckBox("Sausage");
peppers = new JCheckBox("Peppers");
onions = new JCheckBox("Onions");
mushrooms = new JCheckBox("mushrooms");
extracheese = new JCheckBox("Extra Cheeses");
JCheckBox left[] = new JCheckBox[] {pepperoni, peppers, mushrooms};
JCheckBox right[] = new JCheckBox[] {sausage, onions, extracheese};
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx = 0;
gbc.gridy = 0;
add(left, extras, 0, 1, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
add(right, extras, 0, 1, gbc);
gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(2, 12, 2, 12);
totals.add(new JLabel("Subtotal:"), gbc);
gbc.gridy++;
totals.add(new JLabel("Tax:"), gbc);
gbc.gridy++;
totals.add(new JLabel("Total:"), gbc);
gbc.weightx = 0;
gbc.gridx = 1;
gbc.gridy = 0;
lblSubTotal = new JLabel("8.0");
lblTax = new JLabel("0.78");
lblTotal = new JLabel("8.78");
totals.add(lblSubTotal, gbc);
gbc.gridy++;
totals.add(lblTax, gbc);
gbc.gridy++;
totals.add(lblTotal, gbc);
}
protected void add(JComponent[] comps, JComponent parent, int deltaX, int deltaY, GridBagConstraints gbc) {
for (JComponent comp : comps) {
parent.add(comp, gbc);
gbc.gridy += deltaY;
gbc.gridx += deltaX;
}
}
}
}
Lots of different ways to do this, the easiest is probably:
String[] parts = totalLbl.getText().split(":");
String input = parts[1].trim();
Double parsedString = Double.parseDouble(input) * 0.20;
you can do this
str = str.replaceAll("\\D+","");
this will delete non digits from the string
so you would want it to be like this
Double parsedString = Double.parseDouble(input.replaceAll("\\D+","")*0.20);
You can use separate widgets for the label and the value. E.g. The total label, create a JLabel object and set the text with static value "Total:", then for the total value, create a JTextField object and set the text with the actual value. When submitting, get the value from the textfield instead of from the label. Don't forget to call setEditable(false) to the textfield because the textfield is meant to display the value only, not to accept input.
This question already has answers here:
Button for closing a JDialog
(5 answers)
Closed 9 years ago.
I've created Dialog using awt and swing. In this form I hafe JTextField and okButton which is JButton. How to make the Dialog window hide on clicking okButton?
Here is my class's code:
public class QueueDialog extends JFrame implements ActionListener {
private static final long SerialVersionUID = 1L;
private static JTextField field = new JTextField(15);
private Sender sender;
private String incommingMessagesFolderUrl = "/etc/dlp/templates";
public QueueDialog() throws Exception {
sender = new Sender();
// field.setSize(60, 15);
JButton okButton = new JButton("ok");
final JLabel label = new JLabel("Enter the name of queue:");
GridBagLayout gbag = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
setLayout(gbag);
gbc.insets = new Insets(2, 0, 2, 0);
gbc.gridy = 0;
gbc.gridx = 0;
gbag.setConstraints(label, gbc);
gbc.gridy = 1;
gbc.gridx = 0;
gbag.setConstraints(field, gbc);
gbc.gridy = 2;
gbc.gridx = 0;
gbag.setConstraints(okButton, gbc);
add(okButton);
add(field);
add(label);
setTitle("Queue name");
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setVisible(true);
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("ok")) {
// label.setText(field.getText());
send(field.getText());
}
}
});
}
}
As I mentioned in my comment (i.e, the very first comment) setVisible(false) is working absolutely fine on click of Ok button
Please Check this code again Where I have addd the statement in action listener. Just now did it to prove the solution is correct> I was not following this post hoping you must have got your answer in the comment itself
import java.awt.GridBagConstraints;
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.JTextField;
public class QueueDialog extends JFrame implements ActionListener {
private static final long SerialVersionUID = 1L;
private static JTextField field = new JTextField(15);
//private Sender sender;
private String incommingMessagesFolderUrl = "/etc/dlp/templates";
public QueueDialog() throws Exception {
// sender = new Sender();
// field.setSize(60, 15);
JButton okButton = new JButton("ok");
final JLabel label = new JLabel("Enter the name of queue:");
GridBagLayout gbag = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
setLayout(gbag);
// gbc.insets = new Insets(2, 0, 2, 0);
gbc.gridy = 0;
gbc.gridx = 0;
gbag.setConstraints(label, gbc);
gbc.gridy = 1;
gbc.gridx = 0;
gbag.setConstraints(field, gbc);
gbc.gridy = 2;
gbc.gridx = 0;
gbag.setConstraints(okButton, gbc);
add(okButton);
add(field);
add(label);
setTitle("Queue name");
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setVisible(true);
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("ok")) {
System.out.println("Hello");
setVisible(false);
// label.setText(field.getText());
// send(field.getText());
}
}
});
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) throws Exception {
QueueDialog diag = new QueueDialog();
}
}