How to change background color using JComboBox - java

So, basically, the main idea for this project is that I wanted to change the background color by using the jcombobox method. and the background will change with the option chosen when the button(proceed) is clicked. The background color chosen will then be implemented to the next page when the button is clicked. The background that im talking about is the background for all the JPanel(including the other page's JPanel). If (getsource() == f2.btenter2) , it will go to f2(2nd file) btenter2(button)'s when clicked.
public class MainPage extends JFrame implements ActionListener {
JLabel lbTitle, lbWelcome, lbSelect;
JComboBox cbColor;
public Color color[] = {RED, GREEN, BLUE, YELLOW, GRAY};
public String clr[] ={"RED","GREEN","BLUE","YELLOW","GRAY"};
public int index;
JButton btProceed;
public static void main(String[] args) {
MainPage f1 = new MainPage();
f1.setSize(800, 500);
f1.setTitle("Java Assignment");
f1.setVisible(true);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public MainPage() {
lbTitle = new JLabel("Rock-Paper-Scissors-Lizard-Spock");
lbWelcome = new JLabel("Welcome!");
lbSelect = new JLabel("Please select the background color before you proceed:");
lbWelcome.setFont(new Font("Courier", Font.PLAIN, 18));lbSelect.setFont(new Font("Courier", Font.PLAIN, 15)); cbColor = new JComboBox(color);btProceed = new JButton("Proceed");
//1st panel on the north side to set the title
JPanel p1 = new JPanel();
p1.add(lbTitle);
p1.setBackground(new Color(255, 106, 0));
//2nd panel on the center position
JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(14, 1));JPanel a1 = new JPanel();
JPanel a2 = new JPanel();
JPanel a3 = new JPanel();
JPanel e1 = new JPanel();
a1.add(lbWelcome);
a2.add(lbSelect);
a3.add(cbColor);
p2.add(e1);
p2.add(a1);
p2.add(a2);
p2.add(a3);
JPanel p3 = new JPanel();
p3.add(btProceed);
setLayout(new BorderLayout());
add(p1, BorderLayout.NORTH);
add(p2, BorderLayout.CENTER);
add(p3, BorderLayout.SOUTH);
btProceed.addActionListener(this);
cbColor.addActionListener(this);
color().addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
index = cbColor.getSelectedIndex(); //to get the index
if (e.getSource()==cbColor) {
index = cbColor.getSelectedIndex();
p2.setBackground(color[index]);
a1.setBackground(color[index]);
a2.setBackground(color[index]);
a3.setBackground(color[index]);
e1.setBackground(color[index]);
e1.setBackground(color[index]);
p3.setBackground(color[index]);
}
Team f2 = new Team();
GamePage f3 = new GamePage();
GamePage2 f4 = new GamePage2();
Result f5 = new Result();
if (e.getSource()==btProceed) {
this.setVisible(false);
f2.setVisible(true);
f2.setSize(800, 500);
f2.p2.setBackground(color[index]);
f2.p3.setBackground(color[index]);
f2.p4.setBackground(color[index]);
// btenter2 is located in the second file under the same package
if (e.getSource()==f2.btenter2){
this.setVisible(false);
f3.setVisible(true);
f3.setSize(800,500);
f3.p2.setBackground(color[index]);
f3.p3.setBackground(color[index]);
f3.p4.setBackground(color[index]);
f3.p5.setBackground(color[index]);}
if (e.getSource()==f3.btNext){this.setVisible(false);
f4.setVisible(true);
f4.setSize(800,500);
f4.p2.setBackground(color[index]);
f4.p3.setBackground(color[index]);
f4.p4.setBackground(color[index]);
f4.p5.setBackground(color[index]); }
if (e.getSource() == f4.btResult)
{
this.setVisible(false);
f5.setVisible(true);
f5.setSize(800,500);
f5.p2.setBackground(color[index]);
f5.p3.setBackground(color[index]);
f5.p4.setBackground(color[index]);
f5.p5.setBackground(color[index]);}}

Introduction
I started working on this before I saw the OP's latest edit.
Here's the GUI I came up with.
Here's the GUI when you pick red.
Here's the GUI when you pick yellow.
The red GUI uses white text for better contrast. Some background colors work better with black text.
I didn't create an ActionListener for the button. I wanted to demonstrate two things.
A JComboBox can hold any class, not just the String class.
An ActionListener that changes the background and foreground color of a JPanel.
Explanation
When creating a Swing GUI, or almost any Java application, I use the model / view / controller pattern. This pattern allows me to focus on one part of the application at a time and helps me separate my concerns.
So, the first thing I did was create a ColorPair class. The ColorPair class holds a background color, a foreground color, and a String name of the background color. When passing class instances to a JComboBox, the class toString method is used to display the combo box options.
Next, I created a Pallete class. The Pallete class holds a List of ColorPair instances.
Once I created the model, I started on the view. I reorganized the OP's view code so it was easier to read. Generally, I keep all the methods for each Swing component together, and create the Swing components in the order they appear on the JPanel.
I separated the JFrame and JPanel creation into separate methods.
After I was satisfied with the view, I wrote the ActionListener for the JComboBox. I didn't need to pass all the components to the ActionListener class since I could get the children components of the JPanel.
The propagateColors method of the ActionListener is recursive. This is one of those rare instances where a recursive method makes sense in the real world since you can have JPanels as children of a JPanel.
Here's the complete runnable code. I hope it's helpful.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BackgroundColorGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new BackgroundColorGUI());
}
private ColorPair colorPair;
private JPanel mainPanel;
private JPanel buttonPanel;
private Pallete pallete;
public BackgroundColorGUI() {
this.pallete = new Pallete();
}
#Override
public void run() {
JFrame frame = new JFrame("Java Assignment");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTitlePanel(), BorderLayout.BEFORE_FIRST_LINE);
this.mainPanel = createMainPanel();
frame.add(mainPanel, BorderLayout.CENTER);
this.buttonPanel = createButtonPanel();
frame.add(buttonPanel, BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTitlePanel() {
//1st panel on the north side to set the title
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JLabel lbTitle = new JLabel("Rock-Paper-Scissors-Lizard-Spock");
lbTitle.setFont(panel.getFont().deriveFont(Font.BOLD, 24f));
panel.add(lbTitle);
panel.setBackground(new Color(255, 106, 0));
return panel;
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
panel.setLayout(new GridLayout(0, 1, 5, 5));
JPanel e1 = new JPanel();
JLabel dummy = new JLabel(" ");
e1.add(dummy);
panel.add(e1);
JPanel a1 = new JPanel();
JLabel lbWelcome = new JLabel("Welcome!");
lbWelcome.setFont(new Font("Courier", Font.PLAIN, 18));
a1.add(lbWelcome);
panel.add(a1);
JPanel a2 = new JPanel();
JLabel lbSelect = new JLabel("Please select the background "
+ "color before you proceed:");
lbSelect.setFont(new Font("Courier", Font.PLAIN, 15));
a2.add(lbSelect);
panel.add(a2);
JPanel a3 = new JPanel();
JComboBox<ColorPair> cbColor = new JComboBox<ColorPair>();
List<ColorPair> colors = pallete.getColors();
for (ColorPair colorPair : colors) {
cbColor.addItem(colorPair);
}
cbColor.addActionListener(new ColorListener(this));
a3.add(cbColor);
panel.add(a3);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel();
JButton btProceed = new JButton("Proceed");
panel.add(btProceed);
return panel;
}
public JPanel getMainPanel() {
return mainPanel;
}
public JPanel getButtonPanel() {
return buttonPanel;
}
public class ColorListener implements ActionListener {
private BackgroundColorGUI frame;
public ColorListener(BackgroundColorGUI frame) {
this.frame = frame;
}
#Override
public void actionPerformed(ActionEvent event) {
JComboBox<?> comboBox = (JComboBox<?>) event.getSource();
colorPair = (ColorPair) comboBox.getSelectedItem();
propagateColors(frame.getMainPanel(), colorPair);
propagateColors(frame.getButtonPanel(), colorPair);
}
private void propagateColors(JPanel panel, ColorPair colorPair) {
panel.setBackground(colorPair.getBackgroundColor());
panel.setForeground(colorPair.getForegroundColor());
Component[] components = panel.getComponents();
for (Component component : components) {
if (component instanceof JPanel) {
JPanel childPanel = (JPanel) component;
propagateColors(childPanel, colorPair);
}
component.setBackground(colorPair.getBackgroundColor());
component.setForeground(colorPair.getForegroundColor());
}
}
}
public class Pallete {
private final List<ColorPair> colors;
public Pallete() {
this.colors = generatePalleteFactory();
}
private List<ColorPair> generatePalleteFactory() {
List<ColorPair> colors = new ArrayList<>();
colors.add(new ColorPair("Light Grey",
new Color(238, 239, 238), Color.BLACK));
colors.add(new ColorPair("Red", Color.RED, Color.WHITE));
colors.add(new ColorPair("Green", Color.GREEN, Color.BLACK));
colors.add(new ColorPair("Blue", Color.BLUE, Color.WHITE));
colors.add(new ColorPair("Yellow", Color.YELLOW, Color.BLACK));
colors.add(new ColorPair("Grey",
new Color(153, 153, 153), Color.WHITE));
return colors;
}
public List<ColorPair> getColors() {
return colors;
}
}
public class ColorPair {
private final Color backgroundColor;
private final Color foregroundColor;
private final String backgroundColorName;
public ColorPair(String backgroundColorName,
Color backgroundColor, Color foregroundColor) {
this.backgroundColorName = backgroundColorName;
this.backgroundColor = backgroundColor;
this.foregroundColor = foregroundColor;
}
public Color getBackgroundColor() {
return backgroundColor;
}
public Color getForegroundColor() {
return foregroundColor;
}
public String getBackgroundColorName() {
return backgroundColorName;
}
#Override
public String toString() {
return getBackgroundColorName();
}
}
}

The background assigned by the renderer is overriden by the selection background color of the JList that is used in the popup for the combo box.
JComboBox cbColor = new JComboBox(...);
Object child = cbColor.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup)child;
JList list = popup.getList();
list.setSelectionBackground(Color.RED);
Credits to this answer

Related

How to align JButtons using 2 JPanel objects to form a basic java GUI

I'm attempting to re-create the following, extremely basic GUI seen here:
My output is as follows:
I'm having a difficult time formatting the JButtons. For one thing, no matter what I do I cannot get the second Panel, the 'shapePane' to display below the first Panel the 'colorPane' secondly, I am unable to correctly make the y axis of the buttons larger to give them a fatter appearance. Further, the top panel the 'shapePane' seems to dynamically move as the window is resized whereas, the second 'colorPane' stays in a fixed position regardless of the window resizing.
If someone could please provide a bit of assistance I would be immensely grateful
my code thus far is as follows:
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class GUI extends JFrame implements ActionListener, WindowListener
{
private JButton circleButton;
private JButton rectangleButton;
private JButton redButton;
private JButton greenButton;
private JButton blueButton;
private JButton exitButton;
private JTextField textField1;
private JLabel label1;
private JPanel contentPane;
private JPanel colorPane;
private JPanel shapePane;
private JFrame contentFrame;
private int count;
public GUI (String title)
{
super(title);
//setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setBounds(100, 100, 945, 580);
//contentFrame = new JFrame();
//contentPane = new JPanel();
//contentFrame.add(contentPane);
//contentPane.setBorder(new LineBorder(new Color(50, 5, 232), 4, true));
//setContentPane(contentPane);
//contentPane.setLayout(null);
colorPane = new JPanel();
//colorPane.setBorder(new LineBorder(new Color(34, 174, 82), 1, true));
colorPane.setBounds(10, 32, 515, 125);
//contentPane.add(colorPane);
//colorPane.setLayout(null);
shapePane = new JPanel();
shapePane.setBounds(10, 165, 515, 315);
//shapePane.setBorder(new LineBorder(new Color(34, 174, 82), 1, true));
//contentPane.add(shapePane);
//shapePane.setLayout(null);
circleButton = new JButton("Circle");
circleButton.setHorizontalAlignment(SwingConstants.LEFT);
rectangleButton = new JButton("Rectangle");
rectangleButton.setHorizontalAlignment(SwingConstants.LEFT);
greenButton = new JButton("Green");
redButton = new JButton("Red");
blueButton = new JButton("Blue");
exitButton = new JButton("Exit");
textField1 = new JTextField(20);
label1 = new JLabel("current time here");
colorPane.add(redButton, BorderLayout.CENTER);
colorPane.add(greenButton, BorderLayout.CENTER);
colorPane.add(blueButton, BorderLayout.CENTER);
shapePane.add(rectangleButton, BorderLayout.SOUTH);
shapePane.add(circleButton, BorderLayout.SOUTH);
shapePane.add(exitButton, BorderLayout.SOUTH);
getContentPane().add(textField1, BorderLayout.EAST);
getContentPane().add(label1, BorderLayout.WEST);
getContentPane().add(colorPane, BorderLayout.CENTER);
//contentFrame.add(colorPane);
getContentPane().add(shapePane, BorderLayout.CENTER);
//contentFrame.add(shapePane);
}
#Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
#Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
The following should get you started:
Set label's vertical and horizontal position so it appears in the bottom left
and and its desired width. For more layout flexibility consider warping it in a JPanel:
label1 = new JLabel("current time here");
label1.setVerticalAlignment(SwingConstants.BOTTOM);
label1.setHorizontalAlignment(SwingConstants.LEFT);
label1.setPreferredSize(new Dimension(200, 0)); //height is set by the layout manger
getContentPane().add(label1, BorderLayout.WEST);
Use a GridLayout for the buttons pane:
colorPane = new JPanel();
colorPane.setLayout(new GridLayout(2, 3));
Initialize buttons and add them one by one to the grid pane:
redButton = makeButton("Red");
colorPane.add(redButton);
Where makeButton is a method implemented to avoid duplicating code:
private JButton makeButton(String text) {
JButton b = new JButton(text);
b.setHorizontalAlignment(SwingConstants.LEFT);
b.addActionListener(this);
b.setPreferredSize(new Dimension(125, 55)); //set preferred and let Layout manager do its work
return b;
}
Set the text area number of columns. Its height is set by the layout manger:
textArea = new JTextArea(0,20);
getContentPane().add(textArea, BorderLayout.EAST);
Putting it all together:
import java.awt.BorderLayout;
import java.awt.Dimension;
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.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
public class GUI extends JFrame implements ActionListener
{
private final JButton circleButton, rectangleButton, redButton;
private final JButton greenButton, blueButton, exitButton;
private final JTextArea textArea;
private final JLabel label1;
private final JPanel colorPane;
private static final int ROWS = 2, COLS = 3;
public GUI (String title)
{
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//set label's vertical and horizontal position so it appears in the bottom left
//and and its desired width
//for more layout flexibility consider warping it in a JFrame
label1 = new JLabel("current time here");
label1.setVerticalAlignment(SwingConstants.BOTTOM);
label1.setHorizontalAlignment(SwingConstants.LEFT);
label1.setPreferredSize(new Dimension(200, 0)); //height is set by the layout manger
getContentPane().add(label1, BorderLayout.WEST);
//use a GridLayout for the buttons pane
colorPane = new JPanel();
colorPane.setLayout(new GridLayout(ROWS, COLS));
getContentPane().add(colorPane, BorderLayout.CENTER);//each BorderLayout position can hold ONE component
redButton = makeButton("Red");
colorPane.add(redButton);
greenButton = makeButton("Green");
colorPane.add(greenButton);
blueButton = makeButton("Blue");
colorPane.add(blueButton);
rectangleButton = makeButton("Rectangle");
colorPane.add(rectangleButton);
circleButton = makeButton("Circle");
colorPane.add(circleButton);
exitButton = makeButton("Exit");
colorPane.add(exitButton);
//set the text area number of columns. Its height is set by the layout manger
textArea = new JTextArea(0,20);
getContentPane().add(textArea, BorderLayout.EAST);
pack();
}
private JButton makeButton(String text) {
JButton b = new JButton(text);
b.setHorizontalAlignment(SwingConstants.LEFT);
b.addActionListener(this);
b.setPreferredSize(new Dimension(125, 55)); //set preferred and let Layout manager do its work
return b;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(((JButton)e.getSource()).getText()+ " button pressed");
}
public static void main(String[] args) {
new GUI("My Gui").setVisible(true);
}
}
A simple enhancement could be storing all button references in a Map:
public class GUI extends JFrame implements ActionListener
{
private Map <String, JButton> buttons; // a map to hold references to all buttons
private final JTextArea textArea;
private final JLabel label1;
private final JPanel colorPane;
private static final int ROWS = 2, COLS = 3;
private static final String[] BUTTON_LABELS = {"Red","Green", "Blue", "Rectangle", "Circle", "Exit"};
public GUI (String title)
{
super(title);
buttons = new HashMap<>();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//set label's vertical and horizontal position so it appears in the bottom left
//and and its desired width
//for more layout flexibility consider warping it in a JFrame
label1 = new JLabel("current time here");
label1.setVerticalAlignment(SwingConstants.BOTTOM);
label1.setHorizontalAlignment(SwingConstants.LEFT);
label1.setPreferredSize(new Dimension(200, 0)); //height is set by the layout manger
getContentPane().add(label1, BorderLayout.WEST);
//use a GridLayout for the buttons pane
colorPane = new JPanel();
colorPane.setLayout(new GridLayout(ROWS, COLS));
getContentPane().add(colorPane, BorderLayout.CENTER);//each BorderLayout position can hold ONE component
for(String text : BUTTON_LABELS){
JButton button = makeButton(text);
colorPane.add(button);
buttons.put(text, button);
}
//set the text area number of columns. Its height is set by the layout manger
textArea = new JTextArea(0,20);
getContentPane().add(textArea, BorderLayout.EAST);
pack();
}
private JButton makeButton(String text) {
JButton b = new JButton(text);
b.setHorizontalAlignment(SwingConstants.LEFT);
b.addActionListener(this);
b.setPreferredSize(new Dimension(125, 55)); //set preferred and let Layout manager do its work
return b;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(((JButton)e.getSource()).getText()+ " button pressed");
}
public static void main(String[] args) {
new GUI("My Gui").setVisible(true);
}
}

How to close JDialog and save the setting ?

Hi I'm working on a program and I faced a problem when I choose some settings from JDialog then click "ok", which is that the setting didn't save but come back to the original settings.
PS : I'm not English speaker so maybe you observe some mistakes in my text above.
picture
enter image description here
class DrawingSettingWindow extends JDialog {
public DrawingSettingWindow() {
this.setTitle("Drawing Setting Window");
this.setSize(550, 550);
this.setLocationRelativeTo(null);
this.setModal(true);
this.setLayout(new GridLayout(4, 1));
JLabel selectColorText = new JLabel("Select Drawing Color");
colorsList = new JComboBox(colors);
JPanel panel1 = new JPanel();
panel1.add(selectColorText);
panel1.add(colorsList);
add(panel1);
JLabel selectStyleText = new JLabel("Select Drawing Style");
JPanel panel2 = new JPanel();
normal = new JRadioButton("Normal");
normal.setSelected(true);
filled = new JRadioButton("Filled");
ButtonGroup bg = new ButtonGroup();
bg.add(normal);
bg.add(filled);
panel2.add(selectStyleText);
panel2.add(normal);
panel2.add(filled);
add(panel2);
JButton ok = new JButton("OK");
add(ok);
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
this.pack();
this.setVisible(true);
}
The information is there, you just have to extract it from the dialog after the user is done using it. I would give the code above at least two new methods, one a public getColor() method that returns colorsList.getSelectedItem();, the color selection of the user (I'm not sure what type of object this is, so I can't show the method yet). Also another one that gets the user's filled setting, perhaps
public boolean getFilled() {
return filled.isSelected();
}
Since the dialog is modal, you'll know that the user has finished using it immediately after you set it visible in the calling code. And this is where you call the above methods to extract the data.
In the code below, I've shown this in this section: drawingSettings.setVisible(true);
// here you extract the data
Object color = drawingSettings.getColor();
boolean filled = drawingSettings.getFilled();
textArea.append("Color: " + color + "\n");
textArea.append("Filled: " + filled + "\n");
}
For example (see comments):
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class UseDrawingSettings extends JPanel {
private JTextArea textArea = new JTextArea(20, 40);
private DrawingSettingWindow drawingSettings;
public UseDrawingSettings() {
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new ShowDrawSettings()));
setLayout(new BorderLayout());
add(new JScrollPane(textArea));
add(topPanel, BorderLayout.PAGE_START);
}
private class ShowDrawSettings extends AbstractAction {
public ShowDrawSettings() {
super("Get Drawing Settings");
}
#Override
public void actionPerformed(ActionEvent e) {
if (drawingSettings == null) {
Window win = SwingUtilities.getWindowAncestor(UseDrawingSettings.this);
drawingSettings = new DrawingSettingWindow(win);
}
drawingSettings.setVisible(true);
// here you extract the data
Object color = drawingSettings.getColor();
boolean filled = drawingSettings.getFilled();
textArea.append("Color: " + color + "\n");
textArea.append("Filled: " + filled + "\n");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
UseDrawingSettings mainPanel = new UseDrawingSettings();
JFrame frame = new JFrame("UseDrawingSettings");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
#SuppressWarnings("serial")
class DrawingSettingWindow extends JDialog {
private static final String TITLE = "Drawing Setting Window";
private JComboBox<String> colorsList;
private JRadioButton normal;
private JRadioButton filled;
// not sure what colors is, but I'll make it a String array for testing
private String[] colors = {"Red", "Orange", "Yellow", "Green", "Blue"};
public DrawingSettingWindow(Window win) {
super(win, TITLE, ModalityType.APPLICATION_MODAL);
// this.setTitle("Drawing Setting Window");
this.setSize(550, 550); // !! this is not recommended
this.setLocationRelativeTo(null);
this.setModal(true);
this.setLayout(new GridLayout(4, 1));
JLabel selectColorText = new JLabel("Select Drawing Color");
colorsList = new JComboBox(colors);
JPanel panel1 = new JPanel();
panel1.add(selectColorText);
panel1.add(colorsList);
add(panel1);
JLabel selectStyleText = new JLabel("Select Drawing Style");
JPanel panel2 = new JPanel();
normal = new JRadioButton("Normal");
normal.setSelected(true);
filled = new JRadioButton("Filled");
ButtonGroup bg = new ButtonGroup();
bg.add(normal);
bg.add(filled);
panel2.add(selectStyleText);
panel2.add(normal);
panel2.add(filled);
add(panel2);
JButton ok = new JButton("OK");
add(ok);
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
this.pack();
// this.setVisible(true); // this should be the calling code's responsibility
}
public Object getColor() {
return colorsList.getSelectedItem();
}
public boolean getFilled() {
return filled.isSelected();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Foo");
}
}
Side notes:
I've changed your class's constructor to accept a Window parameter, the base class for JFrame, JDialog, and such, and have added a call to the super's constructor. This way, the dialog is a true child window of the calling code (or you can pass in null if you want it not to be).
I recommend not making the dialog visible within its constructor. It is the calling code's responsibility for doing this, and there are instances where the calling code will wish to not make the dialog visible after creating it, for example if it wanted to attach a PropertyChangeListener to it before making it visible. This is most important for modal dialogs, but is just good programming practice.
I didn't know the type of objects held by your combo box, and so made an array of String for demonstration purposes.

Java add a JLabel in the middle of a JButton

I would like to simply add a JLabel into a JButton and center it horizontally. I've tried many thing but the text stay left side... Here is my code :
JLabel labeltest = new JLabel("Simple test");
JButton myButton = new JButton();
myButton.setHorizontalTextPosition(SwingConstants.CENTER);
myButton.add(labeltest);
Create an Icon of the text and give the Icon the foreground/background colors that you want.
I tried this but the problem comes when I had to do button.setenabled(false); after this the text becomes almost invisible
You can set the disabled Icon to be the same as the Icon and it will not be painted in the disabled state:
JButton button = new JButton( new ImageIcon(...) );
button.setDisabledIcon( button.getIcon() );
button.setEnabled(false);
Of course the problem with this approach is that the user doesn't know the button is disabled. So in reality you would need 2 icons:
one for the normal state
one for the disabled state
A JButton is also a java.awt.Container. Thus you can set a layout manager. E.g. you can use a GridBagLayout.
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
JToggleButton toggleButton = new JToggleButton();
JLabel jLabel = new JLabel("3");
JToggleButton.ToggleButtonModel toggleButtonModel = (JToggleButton.ToggleButtonModel) toggleButton.getModel()
ToggleForegroundAction toggleForegroundAction =
new ToggleForegroundAction(toggleButtonModel, Color.WHITE, Color.RED);
toggleForegroundAction.setComponent(jLabel);
toggleButton.setAction(toggleForegroundAction);
toggleButton.setLayout(new GridBagLayout());
toggleButton.add(jLabel, new GridBagConstraints());
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.setLayout(new BorderLayout());
panel.add(toggleButton, BorderLayout.CENTER);
Container contentPane = frame.getContentPane();
contentPane.add(panel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}
An action that toggles the label's foreground color might look like this
public class ToggleForegroundAction extends AbstractAction {
private JComponent component;
private JToggleButton.ToggleButtonModel toggleButtonModel;
private final Color selectedColor;
private final Color unselectedColor;
public ToggleForegroundAction(JToggleButton.ToggleButtonModel toggleButtonModel, Color selectedColor, Color unselectedColor) {
this.toggleButtonModel = toggleButtonModel;
this.selectedColor = selectedColor;
this.unselectedColor = unselectedColor;
}
public void setComponent(JComponent component) {
this.component = component;
setForeground(component, toggleButtonModel.isSelected());
}
#Override
public void actionPerformed(ActionEvent e) {
JComponent targetComponent = this.component;
if (targetComponent == null) {
targetComponent = (JComponent) e.getSource();
}
setForeground(targetComponent, toggleButtonModel.isSelected());
}
private void setForeground(JComponent targetComponent, boolean isSelected) {
Color foreground;
if (isSelected) {
foreground = selectedColor;
} else {
foreground = unselectedColor;
}
targetComponent.setForeground(foreground);
}
}
=>

background image help, JPanel, JFrame, anything?

I want to make a background image for a game I'm designing but I cant figure out the right way to get the effect I want, I want a background that can be seen behind text etc. basically having the background cover the whole JFrame / JPanel not just one section of the layout (e.g. BorderLayout.Center) I think it does this anyway but if it does do that how do I make the background for those transparent to see the background which is behind...
Confusing i know but I hope someone here understands what I am trying to do and can help... this is my current code. I have been playing around with the background so dont read to much in how i have written it.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
public class GamePanel extends JPanel {
private JTextPane playertext;
private JTextField wealthstring, currentwealth;
public GamePanel() {
super();
setLayout(new BorderLayout());
setBackground(Game.getBackgroundColor());
Border raised = BorderFactory.createRaisedBevelBorder();
Border lowered = BorderFactory.createLoweredBevelBorder();
setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(4, 4, 4, 4), (BorderFactory.createCompoundBorder(raised, lowered))));
add(northpanel(), BorderLayout.NORTH);
add(eastpanel(), BorderLayout.EAST);
}
private JLabel northpanel() {
Font northfont = new Font("Engravers MT", Font.BOLD, 12);
ImageIcon banner = new ImageIcon("images/banner.png", "North Background");
playertext = new JTextPane();
playertext.setFont(northfont);
playertext.setEditable(false);
playertext.setText("Player: \n" + Game.getName());
playertext.setBackground(Game.getBackgroundColor());
playertext.setBorder(new EmptyBorder(10,10,10,10));
wealthstring = new JTextField("Money: ");
wealthstring.setFont(northfont);
wealthstring.setEditable(false);
wealthstring.setHorizontalAlignment(wealthstring.RIGHT);
wealthstring.setBorder(null);
wealthstring.setBackground(Game.getBackgroundColor());
currentwealth = new JTextField();
currentwealth.setFont(northfont);
currentwealth.setEditable(false);
currentwealth.setHorizontalAlignment(wealthstring.RIGHT);
currentwealth.setBackground(Game.getBackgroundColor());
currentwealth.setBorder(null);
String wealthrounded = String.format("%.2f", Game.getMoney());
currentwealth.setText(wealthrounded);
JPanel wealthtext = new JPanel();
wealthtext.setLayout(new GridLayout(2, 1));
wealthtext.setBackground(Game.getBackgroundColor());
wealthtext.setBorder(new EmptyBorder(10,10,10,10));
wealthtext.add(wealthstring);
wealthtext.add(currentwealth);
JLabel northpanel = new JLabel();
northpanel.setLayout(new BorderLayout());
northpanel.setIcon(banner);
northpanel.add(new JSeparator(), BorderLayout.PAGE_END);
northpanel.add(playertext, BorderLayout.WEST);
northpanel.add(wealthtext, BorderLayout.EAST);
return northpanel;
}
private JPanel eastpanel() {
JButton tab1 = new JButton("Tab 1");
JButton tab2 = new JButton("Tab 2");
JButton tab3 = new JButton("Tab 3");
JPanel easttabs = new JPanel();
easttabs.setLayout(new GridLayout(1, 3));
easttabs.add(tab1);
easttabs.add(tab2);
easttabs.add(tab3);
JPanel eastpanels = new JPanel();
eastpanels.setLayout(new BorderLayout());
eastpanels.setBackground(Game.getBackgroundColor());
eastpanels.add(easttabs, BorderLayout.NORTH);
return eastpanels;
}
}
So if you already have a JPanel that has your image as Background and you want to add another panel over it with your components you can use Opacity to achieve this. Only the components added to this panel will be visible. Here's the code :
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class TransparentPane extends JPanel {
public TransparentPane() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0f));
g2d.setColor(getBackground());
g2d.fill(getBounds());
g2d.dispose();
}
}
Create a class that extends from JPanel and in its paint method draw an image over it.
Now create a class the extends from JFrame and in its constructor set its contentpane to the object of that JPanel class like below. Now you can add components to jframe.
class SimpleTest extends JFrame {
JButton btn = new JButton("A Game");
public SimpleTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(new CPane());
getContentPane().setBackground(Color.red);
getContentPane().add(btn, BorderLayout.NORTH);
setSize(new Dimension(300, 300));
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SimpleTest();
}
});
}
}
class CPane extends JPanel {
Image back;
public void paintComponent(Graphics g) {
super.paintComponent(g);
try {
back = ImageIO.read(getClass().getResource("back.jpg"));
} catch (Exception ex) {
}
g.drawImage(back, 0, 0, this);
}
}
If you want to make a jpanel transparent then do
panel.setOpaque(false);

Placing of JPanels on the JFrames is not correct

I wrote a program to compose a GUI using swing/awt framework for my assignment. So far, I am able to get the pieces working together, but when I put them all into a JFrame, they are not coming out as expected.
I have recently started working on Java GUI framework, and not sure what is missing in my code. How can I get this working properly?
I am also attaching the screen shots (see at the bottom) of the output I am getting.
public class MainFrame extends JFrame {
public MainFrame() {
addComponentsToPane(this.getContentPane());
}
private void addComponentsToPane(Container pane) {
// Set layout
GridBagConstraints gbc = new GridBagConstraints();
this.setTitle("Test tool");
this.setSize(600, 650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new GridLayout(2, 1));
// Add video JComponent
mMainPanel = new MainPanel();
pane.add(mMainPanel, 0);
// Add conference screen panel
mFeedPanel = new FeedPanel();
pane.add(mFeedPanel, 1);
// Add a button panel
mButtonPanel = new ButtonPanel();
pane.add(mButtonPanel, 2);
this.setResizable(true);
this.setVisible(true);
this.pack();
}
}
// In actual output, there is 1 screen in this panel.
// mScreen1 is derived from JComponent object.
public class MainPanel() extends JPanel {
public MainPanel() {
addMainPanelComponents();
}
private void addMainPanelComponents() {
this.setSize(352, 240);
setBackground(Color.yellow);
setLayout(new GridLayout(1, 2));
add(mScreen);
setVisible(true);
}
}
// In actual output, there are 3 screens in this panel. I have shown code for 1 screen only
// mScreen1 is derived from JComponent object.
public class FeedPanel extends JPanel {
public FeedPanel() {
addFeedPanelComponents();
}
private void addFeedPanelComponents() {
String img1 = "images/screen1.png";
setSize(352, 150);
setBackground(Color.yellow);
setLayout(new GridLayout(1, 3));
Image image1 = ImageIO.read(new File(img1));
mScreen1.setImage(image1);
add(mScreen1);
setVisible(true);
}
}
public class ButtonPanel extends JPanel {
public ButtonPanel() {
addButtonPanelComponents();
}
private void addButtonPanelComponents() {
this.setSize(352, 150);
this.setBackground(Color.yellow);
this.setLayout(new GridLayout(1,
5));
// Add Button to panel
mStartButton = new JButton("Start");
this.add(mStartButton);
mStartButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
StartButtonActionListener(ae);
}
});
mStopButton = new JButton("Stop");
this.add(mStopButton);
mStopButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
StopButtonActionListener(ae);
}
});
setVisible(true);
}
}
This comes by default on running the code.
This comes after manually resizing the frame.
The combination of BorderLayout , GirdLayout and BoxLayout can do this for you(Actually it's not the only choice).
Here is the code:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GridLayoutTest {
public void createUI(){
JFrame frame = new JFrame();
JPanel topPanel = new TopPanel();
JPanel buttomPanel = new ButtomPanel();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(topPanel,BorderLayout.CENTER);
mainPanel.add(buttomPanel,BorderLayout.SOUTH);
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
GridLayoutTest test = new GridLayoutTest();
test.createUI();
}
#SuppressWarnings("serial")
class TopPanel extends JPanel{
public TopPanel(){
setLayout(new GridLayout(2, 3));
ImageIcon icon = new ImageIcon("capture.png");
JLabel label1 = new JLabel(icon);
label1.setVisible(false);
JLabel label2 = new JLabel(icon);
JLabel label3 = new JLabel(icon);
label3.setVisible(false);
JLabel label4 = new JLabel(icon);
JLabel label5 = new JLabel(icon);
JLabel label6 = new JLabel(icon);
add(label1);
add(label2);
add(label3);
add(label4);
add(label5);
add(label6);
}
}
#SuppressWarnings("serial")
class ButtomPanel extends JPanel{
public ButtomPanel(){
JButton startButton = new JButton("start");
JButton stopButton = new JButton("stop");
JButton recordButton = new JButton("record");
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(Box.createHorizontalGlue());
add(startButton);
add(Box.createHorizontalStrut(10));
add(stopButton);
add(Box.createHorizontalStrut(10));
add(recordButton);
add(Box.createHorizontalGlue());
}
}
}
BoxLayout is so good too provide white space and help you to center the component.
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(Box.createHorizontalGlue());
add(startButton);
add(Box.createHorizontalStrut(10));
add(stopButton);
add(Box.createHorizontalStrut(10));
add(recordButton);
add(Box.createHorizontalGlue());
Add Glue before the first component and after the last component will help you too center the component and add strut can help you to provide white space you want. you can refer to https://stackoverflow.com/a/22525005/3378204 for more details.
Here is the effect:
The BoxLayout won't affect your component's size. Hope it can help you.
Try this :
public class Main{
private JFrame f;
private JLabel l1, l2, l3,l4;
private JPanel p1, p2, p3;
private JButton b1, b2, b3;
public Main(){
this.f = new JFrame();
this.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.f.setLayout(new GridLayout(3,1));
this.p1 = new JPanel();
this.p1.setLayout(null)
this.p1.setSize(yoursize);
this.l1 = new JLabel();
this.l1.setBounds(x,y,xspan,yspan);
this.p1.add(l1);
this.p2 = new JPanel();
this.p2.setLayout(new GridLayout(1,3));
this.l2 = new JLabel();
this.l3 = new JLabel();
this.l4 = new JLabel();
this.p2.add(l2);
this.p2.add(l3);
this.p2.add(l4);
this.p3 = new JPanel();
this.p3.setLayout(new GridLayout(1,3));
this.b1 = new JButton();
this.b2 = new JButton();
this.b3 = new JButton();
this.p3.add(b1);
this.p3.add(b2);
this.p3.add(b3);
this.f.add(p1);
this.f.add(p2);
this.f.add(p3);
this.f.pack();
this.f.setResizeable(false)
}}
Add your video components instead of labels and you can change the color of the components as you wish.
Also if you want more control over the size and position of the components, use null layout and place them individually using setBounds() function as once shown in the program above. It is surely time consuming but makes the layout perfect.

Categories

Resources