Guidance required..
Would like to achieve something like the image below whereby the child panel stays the same size but contains up to 4 components. I realize I can achieve this by changing the number of columns in my gridlayout below but in order to keep the child panel the same size I would have to change the border sizes which is something I don't mind doing but it seems a bit cumbersome and am wondering if there is a smart way to go about this. The code I have provided is based on sample code provided to me here
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
public class DynamicGridLayout {
private JPanel ui = null;
DynamicGridLayout() {
initUI();
}
public final void initUI() {
if (ui!=null) return;
ui = new JPanel(new GridBagLayout());
ui.setBorder(new TitledBorder("Parent Panel"));
JPanel controls = new JPanel(new GridLayout(2,0,10,10));
ui.add(controls);
controls.setBackground(Color.RED);
controls.setBorder(new TitledBorder("Child Panel"));
for (int ii=1; ii<5; ii++) {
addLabel(controls, "String " + ii);
}
}
public JComponent getUI() {
return ui;
}
private void addLabel(JPanel panel, String text) {
JPanel controls1 = new JPanel(new GridLayout(3,0,3,3));
controls1.setBackground(Color.green);
controls1.setBorder(new EmptyBorder(75,75,75,75));
panel.add(controls1);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("Three Button/Text Field Combo");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
DynamicGridLayout dgl = new DynamicGridLayout();
f.setContentPane(dgl.getUI());
f.setSize(1050, 720);
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
just for my enjoy, fun,
note have to notify (deepest child required override for min/max/preferredsize from) parent JPanel after LayoutManager is switched back from GridLayout to BorderLayout (unwanted output to see in figure 5th.)
.
.
.
.
.
.
from
.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
public class DynamicGridLayout {
private JFrame f = new JFrame("Three Button/Text Field Combo");
private JPanel ui = new JPanel(new GridBagLayout()) {
#Override
public Dimension getMinimumSize() {
return new Dimension(400, 300);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(800, 600);
}
};
private JPanel controls = new JPanel() {
#Override
public Dimension getMinimumSize() {
return new Dimension(400, 300);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(1050, 720);
}
};
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
DynamicGridLayout() {
initUI();
}
public final void initUI() {
ui.setBorder(new TitledBorder("Parent Panel"));
ui.add(controls);
controls.setBackground(Color.RED);
controls.setBorder(new TitledBorder("Child Panel"));
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.add(ui);
f.add(getCheckBoxPanel(), "South");
f.setMinimumSize(ui.getPreferredSize());
f.setVisible(true);
}
public JComponent getUI() {
return ui;
}
private void addLabel() {
JPanel controls1 = new JPanel(new GridLayout(3, 0, 3, 3));
controls1.setBackground(Color.green);
controls1.setBorder(new EmptyBorder(75, 75, 75, 75));
controls.add(controls1);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(true);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(true);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (controls.getComponentCount() < 1) {
controls.setLayout(new BorderLayout());
addLabel();
makeChange();
} else if (controls.getComponentCount() == 1) {
controls.setLayout(new GridLayout(0, 2, 10, 10));
addLabel();
makeChange();
} else {
controls.setLayout(new GridLayout(2, 0, 10, 10));
addLabel();
makeChange();
}
System.out.println(" Components Count after Adds :" + controls.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = controls.getComponentCount();
if (count > 0) {
if (controls.getComponentCount() == 2) {
controls.setLayout(new BorderLayout());
controls.remove(0);
} else if (controls.getComponentCount() == 3) {
controls.setLayout(new GridLayout(0, 2, 10, 10));
controls.remove(0);
} else {
controls.remove(0);
}
}
makeChange();
System.out.println(" Components Count after Removes :" + controls.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
ui.validate();
}
if (checkReValidate.isSelected()) {
ui.revalidate();
}
if (checkRepaint.isSelected()) {
ui.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
DynamicGridLayout dgl = new DynamicGridLayout();
}
};
SwingUtilities.invokeLater(r);
}
}
Related
I have 3 frames, Main (as the parent) and 2 JInternalFrames (F1 and F2 as children). When a button (inside parent) is pressed, I make an instance of F1 and send it as a parameter to ShowIntrlFrame() so F1 can be displayed inside frmContainter. My question here is, how can I open F2 from F1 and display it on frmContrainer (which is in the Main frame)?
public class Main extends javax.swing.JFrame{
public Main(){
}
private void btnOpenFrmActionPerformed(java.awt.event.ActionEvent evt) {
F1 f1 = new F1();
frmContainer(f1);
}
}
public void ShowIntrlFrame(JInternalFrame f){
f.setSize(1100, 620);
f.setLocation(0, 0);
f.setVisible(true);
frmContainer.removeAll();
frmContainer.add(f, BorderLayout.CENTER);
frmContainer.revalidate();
frmContainer.repaint();
}
What I would do is follow a delegation pattern via dependency injection.
This is, I would "delegate" the functionality need to generate and show the window to some other class and then "inject" that into the workflow as required
I'd start with a concept of a "window manager"...
public interface WindowManager {
enum Window {
FIRST, SECOND;
}
public void openWindow(Window window);
}
At the moment, this is pretty basic and just opens a specified window. The nice thing about this, is we don't care if it's a JInternalFrame or JFrame which gets generated, that's not the callers responsibility.
Next, we make a implementation which supports JDesktopPane
public class DesktopWindowManage implements WindowManager {
private JDesktopPane desktopPane;
private int initialX = 0;
private int initialY = 0;
public DesktopWindowManage(JDesktopPane desktopPane) {
this.desktopPane = desktopPane;
}
public JDesktopPane getDesktopPane() {
return desktopPane;
}
#Override
public void openWindow(Window window) {
JInternalFrame frame = new JInternalFrame(window.name(), true, true, true, true);
frame.setContentPane(makeContentFor(window));
frame.pack();
frame.setLocation(initialX, initialY);
frame.setVisible(true);
try {
frame.setSelected(true);
} catch (PropertyVetoException ex) {
}
desktopPane.add(frame);
frame.toFront();
initialX += 20;
initialY += 20;
}
protected JPanel makeContentFor(Window window) {
switch (window) {
case FIRST: return new FirstPane(this);
case SECOND: return new SecondPane();
}
return null;
}
}
Now, important to note, this class is acting as kind of factory, in that it's generating the content view and JInternalFrame. I'd probably consider making a "content factory" which could be injected into this which would then create the content based on the desired destination, but that's probably getting a little more complicated then is required right now.
Now, before you ask, the actual content is based on JPanel, for example...
public class FirstPane extends JPanel {
public FirstPane(WindowManager windowManager) {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(new JLabel("I am first"), gbc);
JButton showSecond = new JButton("Show second");
showSecond.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.SECOND);
}
});
add(showSecond, gbc);
}
}
public class SecondPane extends JPanel {
public SecondPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
add(new JLabel("I am second"));
}
}
Why? Because it's a JPanel can be added to any container and, generally, we don't care if it's a JInternalFrame or JFrame.
And finally, some kind of "starting point"....
public class MainPane extends JPanel {
private WindowManager windowManager;
private JDesktopPane desktopPane;
public MainPane() {
setLayout(new BorderLayout());
JButton open = new JButton("Open");
desktopPane = new JDesktopPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
windowManager = new DesktopWindowManage(desktopPane);
add(open, BorderLayout.NORTH);
add(desktopPane);
open.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.FIRST);
}
});
}
}
Runnable example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface WindowManager {
enum Window {
FIRST, SECOND;
}
public void openWindow(Window window);
}
public class DesktopWindowManage implements WindowManager {
private JDesktopPane desktopPane;
private int initialX = 0;
private int initialY = 0;
public DesktopWindowManage(JDesktopPane desktopPane) {
this.desktopPane = desktopPane;
}
public JDesktopPane getDesktopPane() {
return desktopPane;
}
#Override
public void openWindow(Window window) {
JInternalFrame frame = new JInternalFrame(window.name(), true, true, true, true);
frame.setContentPane(makeContentFor(window));
frame.pack();
frame.setLocation(initialX, initialY);
frame.setVisible(true);
try {
frame.setSelected(true);
} catch (PropertyVetoException ex) {
}
desktopPane.add(frame);
frame.toFront();
initialX += 20;
initialY += 20;
}
protected JPanel makeContentFor(Window window) {
switch (window) {
case FIRST: return new FirstPane(this);
case SECOND: return new SecondPane();
}
return null;
}
}
public class MainPane extends JPanel {
private WindowManager windowManager;
private JDesktopPane desktopPane;
public MainPane() {
setLayout(new BorderLayout());
JButton open = new JButton("Open");
desktopPane = new JDesktopPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
windowManager = new DesktopWindowManage(desktopPane);
add(open, BorderLayout.NORTH);
add(desktopPane);
open.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.FIRST);
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class FirstPane extends JPanel {
public FirstPane(WindowManager windowManager) {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(new JLabel("I am first"), gbc);
JButton showSecond = new JButton("Show second");
showSecond.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.SECOND);
}
});
add(showSecond, gbc);
}
}
public class SecondPane extends JPanel {
public SecondPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
add(new JLabel("I am second"));
}
}
}
But wait, there's more...
Currently, if you tap "Open" or "Show second" multiple times, you get a bunch of new windows. This may or may not be desirable, but could be easily fixed via the WindowManager, in fact, you could create different WindowManagers based on your needs, for example...
public class DesktopWindowManage implements WindowManager {
private JDesktopPane desktopPane;
private int initialX = 0;
private int initialY = 0;
private Map<Window, JInternalFrame> windowCache = new HashMap<>();
public DesktopWindowManage(JDesktopPane desktopPane) {
this.desktopPane = desktopPane;
}
public JDesktopPane getDesktopPane() {
return desktopPane;
}
#Override
public void openWindow(Window window) {
JInternalFrame frame = windowCache.get(window);
if (frame == null) {
frame = new JInternalFrame(window.name(), true, true, true, true);
frame.setContentPane(makeContentFor(window));
windowCache.put(window, frame);
frame.pack();
frame.setLocation(initialX, initialY);
frame.setVisible(true);
desktopPane.add(frame);
initialX += 20;
initialY += 20;
}
try {
frame.setSelected(true);
} catch (PropertyVetoException ex) {
}
frame.toFront();
}
protected JPanel makeContentFor(Window window) {
switch (window) {
case FIRST:
return new FirstPane(this);
case SECOND:
return new SecondPane();
}
return null;
}
}
I am building a Java Swing app, which I want it will work this way:
When you resize the window, the JScrollPane object (which is within a JSplitPane) should redimension its minimum, maximum and preferred size taking as reference the current window width.
I fixed this settings on the method componentResized() of ComponentAdapter class, however, it doesn't work as suppose must do.
This is the code. I wish you test it on your pc and can help me.
Thanks a lot for your time payed.
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
public class ComVisor extends JFrame
{
private JList imagesList;
private JPanel imagePanel;
private JSplitPane mainPanel;
private JScrollPane scrollPanelRight;
private int width;
public ComVisor(String nameApplication)
{
setFrame(nameApplication);
setComponents();
}
private void setFrame(String nameApplication)
{
setLayout(new BorderLayout(1, 3));
setTitle(nameApplication);
setMinimumSize(new Dimension(400, 200));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(new Dimension(Toolkit.getDefaultToolkit().getScreenSize()));
setLocationRelativeTo(null);
this.addWindowListener(
new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
JOptionPane.showMessageDialog(ComVisor.this, nameApplication + "-Salida");
return;
}
}
);
this.addComponentListener(
new ComponentAdapter()
{
#Override
public void componentResized(ComponentEvent E)
{
width = getWidth();
scrollPanelRight.setPreferredSize(new Dimension(width / 3, 0));
scrollPanelRight.setMinimumSize(new Dimension(width / 7, 0));
scrollPanelRight.setMaximumSize(new Dimension(width / 5 * 4, 0));
return;
}
}
);
}
private void setComponents()
{
String[] a = {"dsdsdsd", "dsdsdkkhskj", "dskhkjdhskjdhksdh", "sdskdhskjhds"};
JButton b = new JButton("Soy un boton xD");
JPanel p = new JPanel();
imagesList = new JList(a);
p.add(b);
imagesList.setVisibleRowCount(100);
scrollPanelRight = new JScrollPane(imagesList);
mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollPanelRight, p);
add(mainPanel, BorderLayout.CENTER);
return;
}
private class Manejador implements ActionListener
{
#Override
public void actionPerformed(ActionEvent listener)
{
return;
}
}
}
and this is the main class, which calls a Comvisor object
import static javax.swing.SwingUtilities.invokeLater;
public class Principal
{
public static void main(String[] args)
{
invokeLater(
new Runnable()
{
#Override
public void run()
{
new ComVisor("ComVisor").setVisible(true);
return;
}
}
);
return;
}
}
I have 4 panels which are added to a frame.
JFrame is set to GridLayout
setLayout(new GridLayout(2, 2));
add(panel1);
add(panel2);
add(panel3);
add(panel4);
When I click on a panel, I want this panel is zoom out and fit to frame's size.
getContentPane().removeAll();
setLayout(new BorderLayout());
panel1.setPreferredSize(new Dimension(getWidth(), getHeight()));
add(panel1, BorderLayout.CENTER);
revalidate();
repaint();
But It didn't work. I think that I cannot set BorderLayout for this frame, it is still GridLayout.
How can I repair it? Thanks
When I click on a panel, I want this panel is zoom out and fit to frame's size.
to use CardLayout
direct answer to the question
.
.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class SwitchLayoutManager {
private JFrame frame = new JFrame();
private JPanel panel1 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.BLACK, 1);
}
};
private JPanel panel2 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.RED, 1);
}
};
private JPanel panel3 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.BLUE, 1);
}
};
private JPanel panel4 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.ORANGE, 1);
}
};
private JPanel panel5 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
public Border getBorder() {
return new LineBorder(Color.GREEN, 1);
}
};
private GridLayout gridLayout = new GridLayout(2, 2);
private BorderLayout borderLayout = new BorderLayout();
public SwitchLayoutManager() {
frame.setLayout(gridLayout);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.add(panel4);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
Timer t = new Timer(2500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (frame.getContentPane().getLayout() == borderLayout) {
frame.getContentPane().removeAll();
frame.setLayout(gridLayout);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.add(panel4);
frame.pack();
//frame.revalidate();
//frame.repaint();
} else if (frame.getContentPane().getLayout() == gridLayout) {
frame.getContentPane().removeAll();
frame.setLayout(borderLayout);
frame.add(panel5);
frame.pack();
//frame.revalidate();
//frame.repaint();
}
}
});
t.setInitialDelay(2500);
t.setRepeats(true);
t.start();
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SwitchLayoutManager();
}
});
}
}
I am dynamically adding items to my JPanel through an ArrayList<Items>. Basically the items object looks like that:
public class Item {
private JComponent component;
private String functionality;
public Item(JComponent component, String functionality) {
super();
this.component = component;
this.functionality = functionality;
}
public JComponent getComponent() {
return component;
}
public void setComponent(JComponent component) {
this.component = component;
}
public String getFunctionality() {
return functionality;
}
public void setFunctionality(String functionality) {
this.functionality = functionality;
}
}
Here I am adding my buttons dynamically: (try the example out if you want)
public class minimumExample extends JFrame {
private JButton addItem;
private JComboBox itemBox;
private String[] itemSelect = { "test1", "test2" };
private JPanel addUpperPane;
private JPanel addLowerPane;
private ArrayList<Item> displayedItems = new ArrayList<Item>();
private JButton upButton;
private JButton downButton;
private JButton deleteButton;
public void createControlPane() {
addUpperPane = new JPanel();
addLowerPane = new JPanel(new GridLayout(0, 1));
addItem = new JButton("Add item");
upButton = new JButton("Up");
downButton = new JButton("Down");
deleteButton = new JButton("Delete");
itemBox = new JComboBox(itemSelect);
addItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(itemBox.getSelectedItem().toString().equals("test1")) {
displayedItems.add(new Item( new ButtonComp().butt(), "test1"));
validate();
repaint();
}
if(itemBox.getSelectedItem().toString().equals("test2")) {
displayedItems.add(new Item( new LabelComp().label(), "test2"));
validate();
repaint();
}
for (int i = 0; i < displayedItems.size(); i++) {
addLowerPane.add(displayedItems.get(i).getComponent());
validate();
repaint();
}
}
});
addUpperPane.add(itemBox, BorderLayout.EAST);
addUpperPane.add(addItem, BorderLayout.WEST);
addUpperPane.add(new JLabel(" | "), BorderLayout.WEST);
addUpperPane.add(upButton, BorderLayout.WEST);
addUpperPane.add(downButton, BorderLayout.WEST);
addUpperPane.add(deleteButton, BorderLayout.WEST);
addUpperPane.add(new JSeparator(JSeparator.HORIZONTAL));
//put everything together
add(addUpperPane, BorderLayout.NORTH);
add(addLowerPane, BorderLayout.SOUTH);
repaint();
}
private void makeLayout() {
setTitle("Test App");
setLayout(new BorderLayout());
setPreferredSize(new Dimension(1000, 500));
createControlPane();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
/**
* starts the GUI
*/
public void start() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
makeLayout();
}
});
}
public static void main(String[] args) throws IOException {
minimumExample ex = new minimumExample();
ex.start();
}
public class ButtonComp extends Component {
public JPanel butt() {
JPanel panel = new JPanel();
JButton button = new JButton("Test1");
JCheckBox check = new JCheckBox();
panel.add(button);
panel.add(check);
return panel;
}
}
public class LabelComp extends Component {
public JPanel label() {
JPanel panel = new JPanel();
JLabel label = new JLabel("Test2");
JCheckBox check = new JCheckBox();
panel.add(label);
panel.add(check);
return panel;
}
}
}
The program basically looks like that:
My problem is that the buttons Up, Down and Delete do not work, because I do not know how to get the selected element from the pane to delete it from the list where all components are in. Any recommendations on how to make this work?
I really appreciate your answer!
UPDATE
I changed my code your specifications #cghislai but it does not work. Try it out yourself:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
public class minimumExample extends JFrame {
private JButton addItem;
private JComboBox itemBox;
private String[] itemSelect = { "test1", "test2" };
private JPanel addUpperPane;
private JPanel addLowerPane;
private List<CheckableItem> displayedItems = new ArrayList<CheckableItem>();
private JButton upButton;
private JButton downButton;
private JButton deleteButton;
public void createControlPane() {
addUpperPane = new JPanel();
addLowerPane = new JPanel(new GridLayout(0, 1));
addItem = new JButton("Add item");
upButton = new JButton("Up");
downButton = new JButton("Down");
deleteButton = new JButton("Delete");
itemBox = new JComboBox(itemSelect);
addItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(itemBox.getSelectedItem().toString().equals("test1")) {
ButtonComp butt = new ButtonComp();
butt.init();
displayedItems.add(butt);
validate();
repaint();
}
if(itemBox.getSelectedItem().toString().equals("test2")) {
// displayedItems.add(new CopyOfItem( new LabelComp(), "test2"));
validate();
repaint();
}
for (int i = 0; i < displayedItems.size(); i++) {
addLowerPane.add(displayedItems.get(i).getComponent());
validate();
repaint();
}
}
});
deleteButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Iterator<CheckableItem> it = displayedItems.iterator();
while (it.hasNext()) {
CheckableItem next = it.next();
if (next.isSelected()) {
addLowerPane.remove(next.getComponent());
it.remove();
continue;
}
}
}
});
addUpperPane.add(itemBox, BorderLayout.EAST);
addUpperPane.add(addItem, BorderLayout.WEST);
addUpperPane.add(new JLabel(" | "), BorderLayout.WEST);
addUpperPane.add(upButton, BorderLayout.WEST);
addUpperPane.add(downButton, BorderLayout.WEST);
addUpperPane.add(deleteButton, BorderLayout.WEST);
addUpperPane.add(new JSeparator(JSeparator.HORIZONTAL));
//put everything together
add(addUpperPane, BorderLayout.NORTH);
add(addLowerPane, BorderLayout.SOUTH);
repaint();
}
private void makeLayout() {
setTitle("Test App");
setLayout(new BorderLayout());
setPreferredSize(new Dimension(1000, 500));
createControlPane();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
/**
* starts the GUI
*/
public void start() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
makeLayout();
}
});
}
public static void main(String[] args) throws IOException {
minimumExample ex = new minimumExample();
ex.start();
}
public abstract class CheckableItem {
protected JCheckBox check;
public boolean isSelected() {
return check.isSelected();
}
public abstract Component getComponent();
}
public class ButtonComp extends CheckableItem {
JPanel panel = new JPanel();
public void init() {
JButton button = new JButton("Test1");
check = new JCheckBox();
panel.add(button);
panel.add(check);
}
#Override
public Component getComponent() {
return panel;
}
}
public class LabelComp extends JPanel {
public void label() {
// JPanel panel = new JPanel();
JLabel label = new JLabel("Test2");
JCheckBox check = new JCheckBox();
add(label);
add(check);
}
}
}
You need to traverse all your items, check if the item checkbox is selected, if this is the case, remove your item from the panel. I would make an abstract CheckableItem class with a getter to the JCheckbox and the Component. Then, for each of you item, if the checkbox is selected, remove the component from the parent.
public abstract class CheckableItem {
protected JCheckbox checkbox;
public boolean isSelected() {
return checkbox.isSelected();
}
public abstract Component getComponent();
}
public class ButtonComp extends CheckableItem {
private Panel panel;
public void init() {
checkbox = new JCheckbox;
panel = new JPanel();
panel.add(new JButton());
panel.add(checkbox);
}
public Component getComponent() {
return panel;
}
}
Then to keep track of your items:
private List<CheckableItem> items = new ArrayList<>();
// ...
ButtonComp comp = new ButtonComp();
comp.init();
items.add(comp);
Then to remove all checked:
Iterator<CheckbleItem> it = items.iterator();
while (it.hasNext()) {
CheckableItem next = it.next();
if (next.isSelected()) {
mainPanel.remove(next.getComponent());
it.remove();
continue;
}
}
Why don't you just have your ButtomComp and LabelComp extend from JPanel? This would solve a lot of your problems I think. For example :
public class ButtonComp extends JPanel {
JButton button;
JCheckBox check = new JCheckBox();
public ButtonComp() {
button = new JButton("Test1");
this.add(button);
this.add(check);
}
}
Then all you would need to do is iterate over your items and look at the checkbox in the components :
for (int i = 0; i < displayedItems.size(); i++) {
if (displayedItems.get(i).check.isSelected()) {
displayedItems.remove(i);
}
}
Note: haven't tested this code. But you should get the idea.
I have created a divider in JSplitPane. I am unable to set the color of divider. I want to set the color of divider. Please help me how to set color of that divider.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SplitPaneDemo {
JFrame frame;
JPanel left, right;
JSplitPane pane;
int lastDividerLocation = -1;
public static void main(String[] args) {
SplitPaneDemo demo = new SplitPaneDemo();
demo.makeFrame();
demo.frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
demo.frame.show();
}
public JFrame makeFrame() {
frame = new JFrame();
// Create a horizontal split pane.
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left = new JPanel();
left.setBackground(Color.red);
pane.setLeftComponent(left);
right = new JPanel();
right.setBackground(Color.green);
pane.setRightComponent(right);
JButton showleft = new JButton("Left");
showleft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(left, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showright = new JButton("Right");
showright.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(right, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showboth = new JButton("Both");
showboth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
c.remove(pane);
c.remove(left);
c.remove(right);
pane.setLeftComponent(left);
pane.setRightComponent(right);
c.add(pane, BorderLayout.CENTER);
if (lastDividerLocation >= 0) {
pane.setDividerLocation(lastDividerLocation);
}
c.validate();
c.repaint();
}
});
JPanel buttons = new JPanel();
buttons.setLayout(new GridBagLayout());
buttons.add(showleft);
buttons.add(showright);
buttons.add(showboth);
frame.getContentPane().add(buttons, BorderLayout.NORTH);
pane.setPreferredSize(new Dimension(400, 300));
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.pack();
pane.setDividerLocation(0.5);
return frame;
}
}
Thanks
Sunil kumar Sahoo
Or, since the divider is a container, you can do the following:
dividerContainer = (BasicSplitPaneDivider) splitPane.getComponent(2);
Component leftBtn = dividerContainer.getComponent(0);
Component rightBtn = dividerContainer.getComponent(1);
dividerContainer.setBackground(Color.white);
dividerContainer.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
dividerContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
dividerContainer.add(toolbar);
dividerContainer.setDividerSize(toolbar.getPreferredSize().height);
This code works for me:
splitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, getSize().width, getSize().height);
super.paint(g);
}
};
}
});
splitPane.setBorder(null);
You can change divider color "g.setColor(new Color(R,G,B))".
This worked for me fine.First you are creating JFrame with it's normal methods such as setDefaultCloseOperation(), setBounds(), getContentPane(). Then create an object from your class then use that to call all the other methods through out the program, in this case I created object called app. One thing you have to keep in mind is that don't forget to use ActionListener e.
Also color changes must go with setBackground() function, while you getting the values from getSource() for the color change.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Main implements ActionListener {
private static void createAndShowGUI() {
Main app=new Main();
// make frame..
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("I am a JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,30,300,120);
frame.setLayout(null);
//Create a split pane
JSplitPane myPane = new JSplitPane();
myPane.setOpaque(true);
myPane.setDividerLocation(150);
app.right = new JPanel();
app.right.setBackground(new Color(255,0,0));
app.left = new JPanel();
app.left.setBackground(new Color(0,255,0));
app.left.setLayout(null);
myPane.setRightComponent(app.right);
myPane.setLeftComponent(app.left);
// make buttons
app.butt1=new JButton("Red");
app.butt2=new JButton("Blue");
app.butt3=new JButton("Green");
// add and size buttons
app.left.add(app.butt1);
app.butt1.setBounds(10,10, 100,20);
app.left.add(app.butt2);
app.butt2.setBounds(10,30, 100,20);
app.left.add(app.butt3);
app.butt3.setBounds(10,50, 100,20);
// set up listener
app.butt1.addActionListener(app);
app.butt2.addActionListener(app);
app.butt3.addActionListener(app);
frame.setContentPane(myPane);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
// check which button and act accordingly
if (e.getSource()==butt1)
right.setBackground(new Color(255,0,0));
if (e.getSource()==butt2)
right.setBackground(new Color(0,0,255));
if (e.getSource()==butt3)
right.setBackground(new Color(0,255,0));
}
public static void main(String[] args) {
// start off..
try {
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel" );
}
catch (Exception e)
{
System.out.println("Cant get laf");
}
Object a[]= UIManager.getInstalledLookAndFeels();
for (int i=0; i<a.length; i++)
System.out.println(a[i]);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
// application object fields
int clickCount=0;
JLabel label;
JButton butt1;
JButton butt2;
JButton butt3;
JPanel left;
JPanel right;
}