Make a custom JButton that can be customized? - java

I want to create my own custom buttons (or that is have a template to create mine own custom buttons). What methods do I need to override to make the same sized button that the JButton makes if I want it to look that same. Because I thought that if you extend a JButton to another button class, a custom button, that had the same size and look as the JButton. But when I put my button up and in the form it makes it really tiny and does not look like a normal button.
What I want is to have at least the same looking button as the JButton has. But I also want to have the add in borders, text and color to foreground and background? What are all of the methods that I would need to override and does anyone have a simple example?
Class: (JButton) -- My Button
import javax.swing.JButton;
public class DougCustomButton extends JButton {
DougCustomButton() {
super();
setBorder(BorderFactory.createLineBorder(Color.BLUE));
}
#Override
public void setPreferredSize(int a, int b) {
//What would I put in here, do I need super()
}
}
Class: (JPanel)
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
public class genericPanel2 extends JPanel {
private static final long serialVersionUID = 1L;
DougCustomButton b2 = new DougCustomButton();
public genericPanel2() {
add(b2);
setPreferredSize(new Dimension(50, 30));
}
}
Class: (JFrame)
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class genericFrame2 {
Dimension dimension = new Dimension(450,450);
JFrame f = new JFrame("Not resizable");
genericPanel2 genericPanel = new genericPanel2();
public static boolean RIGHT_TO_LEFT = false;
public genericFrame2() {
initUI();
}
public static void addComponentsToPane(Container pane) {
}
public final void initUI() {
f.add(genericPanel);
f.setSize(dimension);
f.setResizable(true);
f.setLocationRelativeTo(null);
f.setTitle("Draw Line Test");
//addComponentsToPane(f.getContentPane());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
genericFrame2 ex = new genericFrame2();
ex.f.setVisible(true);
}
}
Screen Shot:
My custom button is the size of a pixel? What is probably causing that?

Sizing information is provided to the layout manager via the getPreferred/Minimum/MaximumSize methods. These generally delegate to the installed UI delegate, which uses, things like, the text, icon and margin properties to determine the size of the button.
Generally speaking, if you want to "customise" a button, you can use the Action API, which provides the means to provide a self contained entity which can easily be applied to different components, such as menus, buttons and even used by the key bindings API
Take a look at How to use Actions for more details

You can set a Border on a regular JButton, just like every other JComponent - perhaps add a Constructor like
public DougCustomButton() {
super();
setBorder(BorderFactory.createLineBorder(Color.BLUE));
// and a font
Font aFont = new Font("Serif", Font.ITALIC | Font.BOLD);
setFont(aFont.deriveFont(18.0f));
}
Read more on How to Use Borders and Font.deriveFont(float).

Related

Swing - Remove selected border and change arrow color of JComboBox

I'm trying to remove the selected border of a JComboBox (top arrow) and change the arrow color (bottom arrow)
If possible, how do I remove the outer border? (the darker gray one)
How do I go about doing this?
So you can do this by implementing a ComboBoxUI, or, actually, subclassing BasicComboBoxUI for example. The second option is better, because you only need to tweak some code in some places and you are ready (instead of implementing your own ComboBoxUI from scratch). So follows the code which does what you requested (hopefully):
import java.awt.Color;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicComboBoxUI;
public class MainComboBoxUI {
public static class MyComboBoxUI extends BasicComboBoxUI {
#Override
protected void installDefaults() {
super.installDefaults();
LookAndFeel.uninstallBorder(comboBox); //Uninstalls the LAF border for both button and label of combo box.
}
#Override
protected JButton createArrowButton() {
//Feel free to play with the colors:
final Color background = Color.CYAN.darker(); //Default is UIManager.getColor("ComboBox.buttonBackground").
final Color pressedButtonBorderColor = Color.RED; //Default is UIManager.getColor("ComboBox.buttonShadow"). The color of the border of the button, while it is pressed.
final Color triangle = Color.BLACK; //Default is UIManager.getColor("ComboBox.buttonDarkShadow"). The color of the triangle.
final Color highlight = background; //Default is UIManager.getColor("ComboBox.buttonHighlight"). Another color to show the button as highlighted.
final JButton button = new BasicArrowButton(BasicArrowButton.SOUTH, background, pressedButtonBorderColor, triangle, highlight);
button.setName("ComboBox.arrowButton"); //Mandatory, as per BasicComboBoxUI#createArrowButton().
return button;
}
}
public static void main(final String[] args) {
final JComboBox<String> combo = new JComboBox<>(new String[]{"A string", "B string 2", "C string 3"});
combo.setUI(new MyComboBoxUI());
final JPanel panel = new JPanel(new GridBagLayout());
panel.add(combo);
panel.setBackground(Color.RED.darker());
final JFrame frame = new JFrame("MainComboBoxUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
First of, we remove the border from the combo box inside installDefaults() method. That will remove the border from both the button and the label. Then we mimic the createArrowButton() method of BasicComboBoxUI to create our own custom button. The default implementation of BasicComboBoxUI.createArrowButton() creates a BasicArrowButton with some construction-time colors. Those colors change the button's triangle's color for example and the background color.
That is for creating a BasicArrowButton. Although, if you want better control over the button (for example instead of a triangle you need an icon and/or some text on the button) then you can simply create a plain JButton inside the createArrowButton() instead of a BasicArrowButton. Then you can initialize it inside the same method, or, preferably modify it inside the configureArrowButton(). Like the following code does:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.plaf.basic.BasicComboBoxUI;
public class MainComboBoxUI2 {
public static class MyComboBoxUI extends BasicComboBoxUI {
#Override
protected void installDefaults() {
super.installDefaults();
LookAndFeel.uninstallBorder(comboBox);
}
#Override
protected JButton createArrowButton() {
final JButton button = new JButton("V");
button.setName("ComboBox.arrowButton"); //Mandatory, as per BasicComboBoxUI#createArrowButton().
return button;
}
#Override
public void configureArrowButton() {
super.configureArrowButton(); //Do not forget this!
arrowButton.setBackground(Color.CYAN.darker());
arrowButton.setForeground(Color.BLUE);
}
}
public static void main(final String[] args) {
final JComboBox<String> combo = new JComboBox<>(new String[]{"A string", "B string 2", "C string 3"});
combo.setUI(new MyComboBoxUI());
combo.setPreferredSize(new Dimension(150, 45)); //Needed to be able to show the button's text.
final JPanel panel = new JPanel(new GridBagLayout());
panel.add(combo);
panel.setBackground(Color.RED.darker());
final JFrame frame = new JFrame("MainComboBoxUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
The only problem with the custom plain JButton approach (ie the second approach) is that the LayoutManager of the JComboBox will not take into account the preferred size of the arrow button if a protected flag inside the UI (named squareButton) is true. If that flag is true, then the button's width is set equal to the button's height, which in turn is set equal to the combo box height. That's why in the second approach, I set the preferred size of the combo box manually to give it a height of 45 pixels which is enough to be able to display the text inside the button (in that specific case, where the text is equal to "V").
You can set the value of this flag for a single UI instance manually by overriding installDefaults() method in the BasicComboBoxUI and setting it to false for example. Otherwise, you can set its value for all combo boxes via calling UIManager.put("ComboBox.squareButton", Boolean.FALSE); in your code early enough (ie before the instantiation of each combo box). But as it turns out, because I tested it, when setting this value to false the size of the button overlaps the display area's size (the display area is where the selected value of the combo box is visible).
After some more digging, I found out that the cause of this problem is that the UI's getMinimumSize(...) method does not take into account the button's insets... That means the default border of the JButton around the text/icon is not accounted for. So after setting the squareButton flag to false, you will also need to override this method.
Putting them all together, you get the following final approach/code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxUI;
public class MainComboBoxUI3 {
public static class MyComboBoxUI extends BasicComboBoxUI {
#Override
protected void installDefaults() {
super.installDefaults();
LookAndFeel.uninstallBorder(comboBox);
}
#Override
protected JButton createArrowButton() {
final JButton button = new JButton("Drop");
button.setName("ComboBox.arrowButton"); //Mandatory, as per BasicComboBoxUI#createArrowButton().
return button;
}
#Override
public void configureArrowButton() {
super.configureArrowButton(); //Do not forget this!
arrowButton.setBackground(Color.CYAN.darker());
arrowButton.setForeground(Color.BLUE);
//arrowButton.setBorder(javax.swing.BorderFactory.createEmptyBorder());
}
//Overrided getMinimumSize to take into account the button's insets for both width and height:
#Override
public Dimension getMinimumSize(final JComponent c) {
final Dimension mindim = super.getMinimumSize(c);
final Insets buttonInsets = arrowButton.getInsets();
return new Dimension(mindim.width + buttonInsets.left + buttonInsets.right, mindim.height + buttonInsets.top + buttonInsets.bottom);
}
}
public static void main(final String[] args) {
UIManager.put("ComboBox.squareButton", Boolean.FALSE); //Set all the combo boxes' button to non-square...
final JComboBox<String> combo = new JComboBox<>(new String[]{"A string", "B string 2", "C string 3"});
combo.setUI(new MyComboBoxUI());
final JPanel panel = new JPanel(new GridBagLayout());
panel.add(combo);
panel.setBackground(Color.RED.darker());
final JFrame frame = new JFrame("MainComboBoxUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
And the result looks like this:
Finally, if you want smaller border for the drop down button (ie the one with text "Drop" in the above picture), you can set the border of the arrowButton to (for example) javax.swing.BorderFactory.createEmptyBorder() inside the configureArrowButton() method...

Access difficulty with ArrayList of panels with buttons

my question is: how do I get the object of my CustomPanel, so that I am able to access its fields (because in my real programm I have some more fields in there) and also am able to delete it from my ArrayList?
I don't know how I have to implement an ActionListener in the Class Window, to somehow get the Object in my Arraylist, which containes the button that got pressed.
Also I am wondering if I am somehow able to implement an ActionListener in the Class CustomPanel which can influence the behaviour of the Object which is an instance of my Class Window.
I have kind of the following code:
public class Window extends JFrame{
ArrayList<CustomPanel> aLCustomPanel = new ArrayList();
JPanel jp = new JPanel();
public Window() {
for(int i=0;i<5;i++){
aLCustomPanel.add(new CustomPanel());
//here I could put the code from the 1 edit - see below
jp.add(aLCustomPanel.get(i));
}
this.add(jp);
}
public static void main(String args[]){
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Window().setVisible(true);
}
});
}
}
class CustomPanel extends JPanel {
private JButton button;
public CustomPanel(){
button = new JButton("button");
this.add(button);
}
public JButton getButton(){
return this.button;
}
}
my Code is much longer and weirder, so I tried to extract the (for this question) importing things.
Thanks for any help in advance!
edit:
for example: I would like to delete the object from the ArrayList, of which the button got pressed.
//imagine this comment in above code
aLCustomPanel.get(aLCustomPanel.size()-1).getButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button_IwantToDeleteYou(e); //here I want to remove the panel, containing the button that got pressed from the above ArrayList, which is located in Class Window
}
});
edit2:
added a missing bracket and fixed some mistakes, code should be ok now.
Your code contained a few "gaps", i.e. missing code, which I filled in, as follows:
Added calls to [JFrame] methods setDefaultCloseOperation() and pack() and setLocationByPlatform(). I suggest you refer to the javadoc for those methods in order to understand what they do.
I set a layout manager for jp class member variable in your Window class.
Yes, you need to register an ActionListener with the JButton in class CustomPanel and that listener should reside in your Window class - the one that extends JFrame.
Here is my rewrite of your code. Note that I changed the name of class Window to CusPanel so as to distinguish between your class and java.awt.Window class. Not that it makes a difference, I just prefer not to use names of classes from the JDK.
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class CusPanel extends JFrame implements ActionListener {
private static final int COUNT = 5;
private ArrayList<CustomPanel> aLCustomPanel = new ArrayList<>();
private JPanel jp = new JPanel(new GridLayout(0, COUNT));
public CusPanel() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
for (int i = 0; i < COUNT; i++) {
aLCustomPanel.add(new CustomPanel(this));
// here I could put the code from the 1 edit - see below
jp.add(aLCustomPanel.get(i));
}
this.add(jp);
pack();
setLocationByPlatform(true);
}
public void actionPerformed(ActionEvent actionEvent) {
Object source = actionEvent.getSource();
if (source instanceof JButton) {
JButton button = (JButton) source;
Container parent = button.getParent();
jp.remove(parent);
jp.invalidate();
jp.repaint();
pack();
// aLCustomPanel.remove(parent); <- optional
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new CusPanel().setVisible(true);
}
});
}
}
class CustomPanel extends JPanel {
private JButton button;
public CustomPanel(ActionListener parent) {
button = new JButton("button");
button.addActionListener(parent);
this.add(button);
}
public JButton getButton() {
return this.button;
}
}
Note that after removing a CustomPanel, the GUI components need to be laid out again and the JFrame should also be resized accordingly. Hence in the actionPerformed() method, I call invalidate(), then repaint() and then pack(). I also think that if you remove a CustomPanel from the GUI, you should also remove it from the ArrayList, but hey, I still don't understand why you want to do this although I obviously don't know the whole story behind you wanting to do this in the first place.
Of-course, since each button (and each CustomPanel) looks exactly the same, you can't really know which button was removed. Again, I assume you see the big picture whereas I don't.

Java/Swing JButton does not display its text and does not perform its action

I want to write a simple street crossing traffic light system. I want to make a button which will start the whole program (open up the GUI of the traffic light system). But already my first button starts to make problems. It doesnt display its text and the action it should perform won't happen. I am really a beginner so its probably some dumb and obvious fault but please have a look I would be really happy ^^
package kreuzung;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class HomeFrame extends JFrame{
public HomeFrame(String title) {
super(title);
this.setLayout(new FlowLayout(FlowLayout.CENTER));
Button test = new Button("noAction");
Container cont = getContentPane();
cont.add(test, BorderLayout.CENTER);
}
}
And this would be the generated button which doesn't do the things its supposed to do
package kreuzung;
import javax.swing.Action;
import javax.swing.JButton;
public class Button extends JButton{
private String actionName;
public Button(String actionName) {
this.actionName = actionName; //set the Action name of this button
JButton button = new JButton(); //instantiate this Button
button.setText(actionName); //set the Action Name as Button Text
button.setSize(30, 30);
button.setBounds(5, 5, 25, 25);
button.addActionListener(new Evt(this.actionName)); //add an Action Listener to the button
//and gets the Action from the Evt Class
}
}
And last but not least here's the Evt class which should take care of the action performing
package kreuzung;
import java.awt.event.*;
import javax.swing.JFrame;
public class Evt implements ActionListener {
private String actionName;
public Evt(String actName) {
this.actionName = actName;
}
#Override
public void actionPerformed(ActionEvent e) {
switch(actionName) {
case "noAction":
JFrame frame = new HomeFrame("Home");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 400);
frame.setVisible(true);
break;
}
}
}
There are several errors in your code:
You shouldn't extend JFrame, see Extends JFrame vs. creating it inside the program
Don't call setBounds(...) the Layout Managers will take care of positioning your components
Don't leave too much extra space between lines or after / before opening / closing braces {} it becomes hard to read
Don' call Button as a class name, it could be confused with java.awt.Button class.
It doesnt display its text and the action it should perform won't happen
In this class:
public class Button extends JButton {
private String actionName;
public Button(String actionName) {
this.actionName = actionName;
JButton button = new JButton();
button.setText(actionName);
button.setSize(30, 30);
button.setBounds(5, 5, 25, 25);
button.addActionListener(new Evt(this.actionName));
}
}
You extend from JButton and then you create a JButton inside of it! so, you have 2 JButtons, the one from the class (inherited) and the one you create inside it. But you're setting the text to the one created inside but you're adding the other one (without text) to your JFrame.
In a metaphor, it's like:
You write in a page something
You get a new white page and add it to your book, instead of adding the one you wrote in to your book.
There's no need to extend JButton in your current program, so just create a new JButton instance and that's it.
Otherwise if you really want to use a custom JButton class do this:
public class MyCustomButton extends JButton { // Change class name
private String actionName;
public MyCustomButton(String actionName) {
super(actionName); //Sets the text
this.actionName = actionName;
button.addActionListener(new Evt(this.actionName));
}
}
You do not really need to create a JButton's children class since you do not add any particular attribute to it.
Instead you should be able to make it works this way:
public class HomeFrame extends JFrame{
private static final String BUTTON_ACTION_NAME = "myActionName";
public HomeFrame(String title) {
super(title);
this.setLayout(new FlowLayout(FlowLayout.CENTER));
JButton test = new JButton();
test.setText(BUTTON_ACTION_NAME);
test.setSize(30, 30);
test.setBounds(5, 5, 25, 25);
test.addActionListener(new Evt(BUTTON_ACTION_NAME));
Container cont = getContentPane();
cont.add(test, BorderLayout.CENTER);
}
}

Adding more mouselisteners to 1 JButton?

Is it possible to add more than 1 mouselistener to a JButton? You know when I click on the button it should change color and text, and do something (e.g system.out.println), and when I click it again it should go back to the previous state, and print something else.
What I've tried:
JButton b = new JButton("First");
b.setBackground(Color.GREEN);
b.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e)
{
b.setBackground(Color.RED);
b.setText("Second");
System.out.println("You've clicked the button");
}
if(b.getModel.isPressed){
b.setBackground(Color.GREEN);
b.setText("Second");
System.out.println("You're back");
}
The problem is that the button doesn't go back to the previous state with the color (green) and text, and I don't how to handle that.
First of all, you shouldn't be using a MouseListener to do these things, because a better listener, ActionListener, was built specifically to be used with JButtons and similar entities to notify programs that a button has been pressed.
Having said that, sure you can add multiple ActionListeners (or MouseListeners) to a JButton, or you can have an ActionListener change its behaviors depending on the state of the program (usually meaning the values held by fields of the class).
A problem with your code and question is that I don't see when you expect or want the button to change its color back to green. If after a certain period of time, then have your ActionListener start a Swing Timer that changes the button's color back to green after x milliseconds.
Edit: I see, you want to toggle color -- then use a boolean field that you toggle or check the button's current color and base the listener's response based on that color.
example
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class ToggleColor extends JPanel {
public ToggleColor() {
JButton button = new JButton(new MyButtonAction());
button.setBackground(Color.GREEN);
add(button);
}
private static void createAndShowGui() {
ToggleColor mainPanel = new ToggleColor();
JFrame frame = new JFrame("ToggleColor");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class MyButtonAction extends AbstractAction {
// !! parallel arrays being used below -- avoid if possible
private static final String[] TEXT = {"First", "Second", "Third"};
private static final Color[] COLORS = {Color.GREEN, Color.RED, new Color(108, 160, 220)};
private int index = 0;
public MyButtonAction() {
super(TEXT[0]);
}
#Override
public void actionPerformed(ActionEvent e) {
index++;
index %= TEXT.length;
putValue(NAME, TEXT[index]);
Component c = (Component) e.getSource();
c.setBackground(COLORS[index]);
}
}
This uses an AbstractAction class which is like an ActionListener but on "steroids"
You should only register one lister, but that listener will maintain some state regarding the number for mouse clicks. A simple if/else block will change the actions and change the text on the button label.

Using JTabbedPane with JPanels that need to share data

In my application, I have several custom JPanels added to a JTabbedPane. A single JPanel offers a piece of functionality, I've added them to JTabbedPane so that the user can switch between modules easily.
All of those custom JPanels operate on the same set of data, meaning if one of the modules has to change something in the data (for instance, a List), all other panels should be aware of that change and react accordingly.
However, with JTabbedPane, you first need to instantiate those JPanels to add them to JTabbedPane - and you do it once.
I have one problem - suppose user adds something to the collection in panel A (which is shared by all those panels) and switches to panel B. What should happen in this case? How is B supposed to know that something has been added to that collection?
My idea was to simply detect a tab switch event, and call the method of B to take the new data into account. But I feel this is not how it should be done.
What could you suggest?
In the example below, each panel in the tabbed pane has its own JComboBox that listens to a common ComboBoxModel. When the common model is updated, by clicking Update, each listening JComboBox sees the change.
I never need any two combo boxes to share a model. My panels contain completely different JComponent instances, but the look and data those components display depend on several collections common to all of those panels.
You may be able to leverage the observer pattern, examined here. The exact details depend on your use case, but the PropertyChangeListener examples are worth studying.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.util.Date;
import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
/**
* #see https://stackoverflow.com/a/37514928/230513
* #see https://stackoverflow.com/questions/8752037
* #see https://stackoverflow.com/a/37222598/230513
*/
public class TabTest {
private static final int N = 5;
private final JTabbedPane pane = new JTabbedPane();
private final DefaultComboBoxModel model = new DefaultComboBoxModel(
new String[]{"Alpher", "Bethe", "Gamow", "Dirac", "Einstein"});
public TabTest() {
for (int i = 0; i < N; i++) {
Color color = Color.getHSBColor((float) i / N, 1, 1);
pane.add("Tab " + String.valueOf(i), new TabContent(i, color));
}
}
private class TabContent extends JPanel {
private TabContent(int i, Color color) {
setOpaque(true);
setBackground(color);
add(new JComboBox(model));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}
private void display() {
JFrame f = new JFrame("TabColors");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(pane);
JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
p.add(new JButton(new AbstractAction("Update") {
#Override
public void actionPerformed(ActionEvent e) {
model.addElement(new Date());
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new TabTest().display();
}
});
}
}

Categories

Resources