Moving left right in a JPanel - java

I want to add a number of buttons to a JPanel dynamically, When I add it only shows a fixed number of buttons,
So I would like to add a left right moving for viewing all buttons
How we can do this, Is there any java component to do this?
public class TestJPanel extends JFrame {
JPanel statusBar;
public TestJPanel() {
setLayout(new BorderLayout());
statusBar = new JPanel();
statusBar.setLayout(new BoxLayout(statusBar, BoxLayout.LINE_AXIS));
add("South", statusBar);
for (int i = 1; i < 20; i++) {
statusBar.add(new Button("Button" + i));
}
} }

Here is some old code I had lying around that will automatically add/remove left/right buttons as required:
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
public class ScrollContainer extends JPanel
implements ActionListener, ComponentListener
{
private Container container;
private List<Component> removedComponents = new ArrayList<Component>();
private JButton forwardButton;
private JButton backwardButton;
public ScrollContainer(Container container)
{
this.container = container;
setLayout( new BorderLayout(5, 0) );
addComponentListener( this );
// Create buttons to control scrolling
backwardButton = new BasicArrowButton( BasicArrowButton.WEST );
configureButton( backwardButton );
forwardButton = new BasicArrowButton( BasicArrowButton.EAST);
configureButton( forwardButton );
// Layout the panel
add( backwardButton, BorderLayout.WEST );
add( container );
add( forwardButton, BorderLayout.EAST );
}
// Implement the ComponentListener
public void componentResized(ComponentEvent e)
{
// When all components cannot be shown, add the forward button
int freeSpace = getSize().width - container.getPreferredSize().width;
if (backwardButton.isVisible())
freeSpace -= backwardButton.getPreferredSize().width;
forwardButton.setVisible( freeSpace < 0 );
// We have free space, redisplay removed components
while (freeSpace > 0 && ! removedComponents.isEmpty())
{
if (removedComponents.size() == 1)
freeSpace += backwardButton.getPreferredSize().width;
Object o = removedComponents.get(removedComponents.size() - 1);
Component c = (Component)o;
freeSpace -= c.getSize().width;
if (freeSpace >= 0)
{
container.add(c, 0);
removedComponents.remove(removedComponents.size() - 1);
}
}
// Some components still not shown, add the backward button
backwardButton.setVisible( !removedComponents.isEmpty() );
// repaint();
}
public void componentMoved(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
// Implement the ActionListener
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
// Scroll the components in the container
if (source == forwardButton)
scrollForward();
else
scrollBackward();
}
/*
* Simulate scrolling forward
* by remove the first component from the container
*/
private void scrollForward()
{
if (container.getComponentCount() == 1)
return;
// Remove and save the first component
Component c = container.getComponent(0);
container.remove( c );
removedComponents.add( c );
// Allow for backwards scrolling
backwardButton.setVisible( true );
// All components are showing, hide the forward button
int backwardButtonWidth = backwardButton.getPreferredSize().width;
int containerWidth = container.getPreferredSize().width;
int panelWidth = getSize().width;
if (backwardButtonWidth + containerWidth <= panelWidth)
forwardButton.setVisible( false );
// Force a repaint of the panel
revalidate();
repaint();
}
/*
* Simulate scrolling backward
* by adding a removed component back to the container
*/
private void scrollBackward()
{
if (removedComponents.isEmpty())
return;
// Add a removed component back to the container
Object o = removedComponents.remove(removedComponents.size() - 1);
Component c = (Component)o;
container.add(c, 0);
// Display scroll buttons when necessary
if (removedComponents.isEmpty())
backwardButton.setVisible( false );
forwardButton.setVisible( true );
revalidate();
repaint();
}
private void configureButton(JButton button)
{
button.setVisible( false );
button.addActionListener( this );
}
private static void createAndShowGUI()
{
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add( new JButton("one") );
toolBar.add( new JButton("two222222") );
toolBar.add( new JButton("three") );
toolBar.add( new JButton("four") );
toolBar.add( new JButton("five") );
toolBar.add( new JButton("six666666666") );
toolBar.add( new JButton("seven") );
toolBar.add( new JButton("eight") );
toolBar.add( new JButton("nine9999999") );
toolBar.add( new JButton("ten") );
ScrollContainer container = new ScrollContainer(toolBar);
JFrame frame = new JFrame("Scroll Container");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(container, BorderLayout.NORTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

public TestJPanel()
{
setLayout(new BorderLayout());
statusBar = new JPanel();
statusBar.setLayout(new BoxLayout(statusBar, BoxLayout.LINE_AXIS));
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(statusBar)
add(scrollPane, BorderLayout.SOUTH);
for (int i = 1; i < 20; i++) {
statusBar.add(new Button("Button" + i));
}
}
If the look does not satisfy you, see for example Custom design JScollPane Java Swing and read about custom Look and Feels

I got one solution , we can implement left right navigation by using JViewport
public class StatusBar extends JFrame {
private final JPanel statusBar;
private final JPanel leftrightPanel;
private final JPanel myPane;
private final JButton rightButton;
private final JButton leftButton;
private final JViewport viewport;
private final JPanel iconsPanel;
private JButton button;
public StatusBar() {
setLayout(new BorderLayout());
statusBar = new JPanel();
statusBar.setLayout(new BorderLayout());
iconsPanel = new JPanel();
iconsPanel.setLayout(new BoxLayout(iconsPanel, BoxLayout.LINE_AXIS));
iconsPanel.setBackground(Color.LIGHT_GRAY);
viewport = new JViewport();
viewport.setView(iconsPanel);
leftrightPanel = new JPanel();
leftrightPanel.setBackground(Color.WHITE);
rightButton = new BasicArrowButton(BasicArrowButton.WEST);
rightButton.addActionListener((ActionEvent e) -> {
int iconsPanelStartX = iconsPanel.getX();
if (iconsPanelStartX < 0) {
Point origin = viewport.getViewPosition();
if (Math.abs(iconsPanelStartX) < 20) {
origin.x -= Math.abs(iconsPanelStartX);
} else {
origin.x -= 20;
}
viewport.setViewPosition(origin);
}
});
leftButton = new BasicArrowButton(BasicArrowButton.EAST);
leftButton.addActionListener((ActionEvent e) -> {
Point origin = viewport.getViewPosition();
origin.x += 20;
viewport.setViewPosition(origin);
});
leftrightPanel.add(rightButton);
leftrightPanel.add(leftButton);
statusBar.add(viewport);
statusBar.add(leftrightPanel, BorderLayout.LINE_END);
add(statusBar,BorderLayout.SOUTH);
myPane = new JPanel();
add(myPane, BorderLayout.CENTER);
for (int i = 1; i < 20; i++) {
button =new JButton("Button " + i);
iconsPanel.add(button);
}
}}

Related

How to set width of GridBagLayout?

I have a JPanel and i am adding gridbagLayouts to it.
but sometimes the gridbaglayout is not big enough to show the title of a tree
like this:
how can i set the width of this ?
JPanel F_panel = new JPanel();
String Fs_desc = MpaResourceBundle.getString(Ps_label, Constants.RB_PACKAGE);
String Fs_dir = P_type.getRepoDir();
String Fs_title = Fs_desc + " (" + Fs_dir + ")";
F_panel.setBorder(BorderFactory.createTitledBorder(Fs_title));
F_panel.setLayout(new GridBagLayout());
GridBagConstraints F_constr = new GridBagConstraints();
F_constr.anchor = GridBagConstraints.NORTHWEST;
F_constr.insets = new Insets(0, 0, 0, 0);
F_constr.gridx = 0;
F_constr.gridy = 0;
for (PluginID F_pid : dataHolder.getAllPluginIDs())
{
COSDependencyMetaInfoTree F_cosDepMITree = new COSDependencyMetaInfoTree(P_type,
null,
dataHolder.getMasterCOSLogObjectNames(),
F_pid,
dataHolder.getRepoObjectOwners(),
null,
P_coll);
if (F_cosDepMITree.getRowCount() > 1)
{
P_treeList.add(F_cosDepMITree);
F_panel.add(F_cosDepMITree, F_constr);
F_constr.gridy++;
}
}
if (F_panel.getComponents().length > 0)
{
add(F_panel, P_gbc);
P_gbc.gridy++;
}
Maybe you can set a tooltip for the panel to display the entire border title when the mouse hovers over the title:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class TitledBorderTest
{
private static void createAndShowUI()
{
UIManager.getDefaults().put("TitledBorder.titleColor", Color.RED);
Border lowerEtched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
String titleText = "Long title that will be truncated in the panel";
TitledBorder title = BorderFactory.createTitledBorder(lowerEtched, titleText);
JPanel panel = new JPanel()
{
#Override
public String getToolTipText(MouseEvent e)
{
Border border = getBorder();
if (border instanceof TitledBorder)
{
TitledBorder tb = (TitledBorder)border;
FontMetrics fm = getFontMetrics( getFont() );
int titleWidth = fm.stringWidth(tb.getTitle()) + 20;
Rectangle bounds = new Rectangle(0, 0, titleWidth, fm.getHeight());
return bounds.contains(e.getPoint()) ? super.getToolTipText() : null;
}
return super.getToolTipText(e);
}
};
panel.setBorder( title );
panel.setToolTipText(title.getTitle());
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}

jPopupMenu not hiding, after clicking background jFrame

I'm using a JPopupMenu which contains multiple jCheckBoxMenuItem. User can check/uncheck several CheckBox. But when I click on JFrame the PopupMenu is not hiding.
This the entire code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PopupTest extends JFrame {
JButton button1;
public PopupTest() {
setTitle("Popup Test !");
setSize(400, 400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
button1 = new JButton("Click me!");
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = 250; // this count value is dynamic
JPopupMenu menu = new JPopupMenu();
JCheckBoxMenuItem item = null;
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JScrollPane scrollPane = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(125, 200));
for (int i = 1; i <= count; i++) {
item = new JCheckBoxMenuItem("Page : " + i, new ImageIcon("test.png"));
item.setHorizontalTextPosition(JMenuItem.RIGHT);
item.addActionListener(new OpenAction(menu, button1));
panel.add(item);
}
menu.add(scrollPane);
JCheckBoxMenuItem selectAll = new JCheckBoxMenuItem("Select All", new ImageIcon("test.png"));
selectAll.addActionListener(new OpenAction(menu, button1));
menu.insert(selectAll, 0);
if (!menu.isVisible()) {
Point p = button1.getLocationOnScreen();
menu.setLocation((int) p.getX(), (int) p.getY() + button1.getHeight());
menu.setVisible(true);
} else {
menu.setVisible(false);
}
}
});
add(button1);
}
private static class OpenAction implements ActionListener {
private JPopupMenu menu;
private JButton button;
private OpenAction(JPopupMenu menu, JButton button) {
this.menu = menu;
this.button = button;
}
#Override
public void actionPerformed(ActionEvent e) {
String chkBoxText = e.getActionCommand().toString();
AbstractButton aButton = (AbstractButton) e.getSource();
boolean selected = aButton.getModel().isSelected();
Icon checkedIcon = new ImageIcon("test1.png");
Icon uncheckedIcon = new ImageIcon("test.png");
JScrollPane pane = null;
JViewport viewport = null;
JPanel panel = null;
JCheckBoxMenuItem item = null;
pane = (JScrollPane) menu.getComponent(1); //0th component is "Select All" check box
viewport = pane.getViewport();
panel = (JPanel) viewport.getComponent(0);
int totalChkBoxComponent = panel.getComponentCount();
if (selected) {
System.out.println(chkBoxText + " is Checked!");
if (chkBoxText.trim().equalsIgnoreCase("select all")) {
for (int i = 0; i < totalChkBoxComponent; i++) {
item = (JCheckBoxMenuItem) panel.getComponent(i);
item.setSelected(selected);
item.setIcon(item.isSelected() ? checkedIcon : uncheckedIcon);
}
}
} else if (!selected) {
System.out.println(chkBoxText + " is Un-Checked!");
if (chkBoxText.trim().equalsIgnoreCase("select all")) {
for (int i = 0; i < totalChkBoxComponent; i++) {
item = (JCheckBoxMenuItem) panel.getComponent(i);
item.setSelected(selected);
item.setIcon(item.isSelected() ? checkedIcon : uncheckedIcon);
}
} else { // this is for, after checking "Select All", if any other is unchecked, then "Select ALL" should be unchecked.
item = (JCheckBoxMenuItem) menu.getComponent(0);
item.setSelected(selected);
item.setIcon(selected ? checkedIcon : uncheckedIcon);
}
}
aButton.setIcon(aButton.isSelected() ? checkedIcon : uncheckedIcon);
}
}
public static void main(String args[]) {
new PopupTest();
}
}
Please help. Thanks.
First of all, your code is not really the best way to do such thing. You shouldn't create a new menu each time the button is clicked but rather create it once and keep a reference to it as field.
The reason PopupMenu does not hide is that you explicitly call setVisible(true); and you try to setVisible(false); in the very same ActionListener which is assigned to the button, not the frame.
You could:
1. Add another listener to the frame to set menu visiblity to false when clicked
2. Use show method instead of setVisible:
menu.show(button1, 0, button1.getHeight());
instead of
menu.setLocation((int) p.getX(), (int) p.getY() + button1.getHeight());
menu.setVisible(true);
However in our case, this causes other issues with menu disappearing. IMO the best way is to redesign your code.

How to change the size of button in a Scroll Panel

I want to change the size of buttons. I want to set a SQUARE type view of each button but unfortunately it is giving a rectangular look. I am getting a square type look only if I set the number of rows to 20 or 25. Right now my GUI looks like the following: .
I have tried to change it from buttons[i][j].setMaximumSize(new Dimension( 20, 20)) , Where buttons is the name of array. I have also tried buttons[i][j].setsize but still it has no effect on it. I am setting it from : bPanel.setLayout(new GridLayout(x,y)) and I thing this is the main cause of the problem. Can any one also tell me that how can I set it to layout manager?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.event.*;
import javax.swing.JFrame;
import sun.util.calendar.Gregorian;
public class Final_GUI extends JFrame implements ActionListener {
JLabel label;
ButtonGroup cbg;
JRadioButton radio_1;
JRadioButton radio_2;
JRadioButton radio_3;
JCheckBox checkbox_1;
JCheckBox checkbox_2;
JCheckBox checkbox_3;
JScrollPane scrollpane_1;
JComboBox combobox_1;
JList list_1;
JScrollPane sp_list_1;
JComboBox combobox_2;
JButton Orange;
JButton Exit;
JLabel for_text;
int x=200;
int y=100;
int check [][]= new int [x][y];
JFrame frame = new JFrame();
JButton[][] buttons = new JButton[x][y];
JPanel mPanel = new JPanel();
JPanel bPanel = new JPanel();
JPanel cPanel = new JPanel();
JTextArea scoreKeeper = new JTextArea();
int[][] intArray = new int[x][y];
public Final_GUI() {
butGen();
score();
Final_GUILayout customLayout = new Final_GUILayout();
getContentPane().setFont(new Font("Helvetica", Font.PLAIN, 12));
getContentPane().setLayout(customLayout);
label = new JLabel("Shortest Path Finding Algorithm");
getContentPane().add(label);
cbg = new ButtonGroup();
radio_1 = new JRadioButton("radio_1", false);
cbg.add(radio_1);
getContentPane().add(radio_1);
radio_2 = new JRadioButton("radio_2", false);
cbg.add(radio_2);
getContentPane().add(radio_2);
radio_3 = new JRadioButton("radio_3", false);
cbg.add(radio_3);
getContentPane().add(radio_3);
checkbox_1 = new JCheckBox("checkbox_1");
getContentPane().add(checkbox_1);
checkbox_2 = new JCheckBox("checkbox_2");
getContentPane().add(checkbox_2);
checkbox_3 = new JCheckBox("checkbox_3");
getContentPane().add(checkbox_3);
bPanel.setLayout(new GridLayout(x,y));
mPanel.setLayout(new BorderLayout());
mPanel.add(bPanel, BorderLayout.CENTER);
scrollpane_1 = new JScrollPane(mPanel);
scrollpane_1.setViewportView(mPanel);
getContentPane().add(scrollpane_1);
combobox_1 = new JComboBox();
combobox_1.addItem("Size1");
combobox_1.addItem("Size2");
getContentPane().add(combobox_1);
DefaultListModel listModel_list_1 = new DefaultListModel();
listModel_list_1.addElement("Black");
listModel_list_1.addElement("Green");
list_1 = new JList(listModel_list_1);
sp_list_1 = new JScrollPane(list_1);
getContentPane().add(sp_list_1);
combobox_2 = new JComboBox();
combobox_2.addItem("Additional Data");
combobox_2.addItem("Additional Data2");
getContentPane().add(combobox_2);
Orange = new JButton("Orange");
getContentPane().add(Orange);
Exit = new JButton("Exit");
getContentPane().add(Exit);
for_text = new JLabel("Just For some text");
getContentPane().add(for_text);
setSize(getPreferredSize());
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
private void butGen()
{
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
buttons[i][j] = new JButton(String.valueOf(i)+"x"+String.valueOf(j));
buttons[i][j].setActionCommand("button" +i +"_" +j);
buttons[i][j].addActionListener(this);
buttons[i][j].setMaximumSize(new Dimension( 20, 20));
bPanel.add(buttons[i][j]);
}
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().contains("button"))
{
String str = e.getActionCommand().replaceAll("button", "");
System.out.println(str);
String[] v = str.split("_");
int i = Integer.parseInt(v[0]);
int j = Integer.parseInt(v[1]);
intArray[i][j]++;
if(check[i][j]!=1){
buttons[i][j].setBackground(Color.black);
check[i][j]=1;
}
else{
buttons[i][j].setBackground(null);
check[i][j]=0;
}
System.out.println(e.getActionCommand() +" " +(i) +" " +(j));
score();
if(checkbox_1.isSelected())
{
buttons[i][j].setBackground(Color.GREEN);
}
}
}
private void score()
{
for(int i=0;i<x;i++)
for(int j=0;j<y;j++)
buttons[i][j].setText("");
}
public static void main(String args[]) {
Final_GUI window = new Final_GUI();
window.setTitle("SHORTEST PATH FINDING ALGORITHM");
window.setBackground(Color.black);
// window.setSize(800, 300);
window.setResizable(true);
window.resize(200, 500);
window.pack();
window.show();
}
}
GUI LAYOUT
class Final_GUILayout implements LayoutManager {
public Final_GUILayout() {
}
public void addLayoutComponent(String name, Component comp) {
}
public void removeLayoutComponent(Component comp) {
}
public Dimension preferredLayoutSize(Container parent) {
Dimension dim = new Dimension(0, 0);
Insets insets = parent.getInsets();
dim.width = 1053 + insets.left + insets.right;
dim.height = 621 + insets.top + insets.bottom;
return dim;
}
public Dimension minimumLayoutSize(Container parent) {
Dimension dim = new Dimension(0,0);
return dim;
}
public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();
Component c;
c = parent.getComponent(0);
if (c.isVisible()) {c.setBounds(insets.left+368,insets.top+24,304,64);}
c = parent.getComponent(1);
if (c.isVisible()) {c.setBounds(insets.left+8,insets.top+120,72,24);}
c = parent.getComponent(2);
if (c.isVisible()) {c.setBounds(insets.left+8,insets.top+144,72,24);}
c = parent.getComponent(3);
if (c.isVisible()) {c.setBounds(insets.left+8,insets.top+168,72,24);}
c = parent.getComponent(4);
if (c.isVisible()) {c.setBounds(insets.left+88,insets.top+120,72,24);}
c = parent.getComponent(5);
if (c.isVisible()) {c.setBounds(insets.left+88,insets.top+144,72,24);}
c = parent.getComponent(6);
if (c.isVisible()) {c.setBounds(insets.left+88,insets.top+168,72,24);}
c = parent.getComponent(7);//Panel
if (c.isVisible()) {
c.setBounds(insets.left+168,insets.top+120,704,488);
}
c = parent.getComponent(8);
if (c.isVisible()) {c.setBounds(insets.left+880,insets.top+120,160,160);}
c = parent.getComponent(9);
if (c.isVisible()) {c.setBounds(insets.left+24,insets.top+232,128,216);}
c = parent.getComponent(10);
if (c.isVisible()) {c.setBounds(insets.left+880,insets.top+296,160,216);}
c = parent.getComponent(11);
if (c.isVisible()) {c.setBounds(insets.left+904,insets.top+528,112,24);}
c = parent.getComponent(12);
if (c.isVisible()) {c.setBounds(insets.left+888,insets.top+568,144,32);}
c = parent.getComponent(13);
if (c.isVisible()) {c.setBounds(insets.left+16,insets.top+472,120,48);}
}
}
GridLayout works by providing equal amount of space to each of the components, making each component fill each cell.
Take a look at How to use GridLayout for more details.
If you want a LayoutManager that provides you with the finest of control, but which will (unless you tell it otherwise) use the components preferred/minimum/maximum size hints, you should consider trying something like GridBagLayout instead
Take a look at How to use GridBagLayout for more details
Using GridBagLayout you can set the size of the components inside.
Another way to do it would be to create a custom button inherited from JButton class and overwrite the method SetSize(int width, int height) and setting width=height.
You can do something like this:
public class SquareButton extends JButton{
#Override
public void setSize(int width, int height) {
super.setSize(width, width);
}
}
With that, you are defining a new class of JButton that inherits all the methods from JButton, but all the instances of this SquareButton class will have the same width and height.
Maybe you don't need to do it, but I think it works. On the other hand, using this new class you don't be able to set another size relationship for your buttons.
Another way could be to create a new method in the new SquareButton class to set your desired size (or relationship width/height), instead of overwrite the SetSize(int width, int height).

DnD - Why is dragged label displayed below other components?

I've written a basic DnD program that has four JLabels in a row. I've noticed
that when I drag a label to the left, it is displayed below the next label. However,
when I drag the label to the right, it is displayed above the next label.
The labels are added in order, left to right. So the dragged label is being
displayed below other labels that were added before the dragged label, and displayed
above other labels that were added after the dragged label.
Can anyone explain why this happens? Can anyone offer a fix so that the dragged label
is displayed above the other labels?
Thanks.
source code:
public class LabelDnd extends JPanel {
private JLabel[] labels;
private Color[] colors = { Color.BLUE, Color.BLACK, Color.RED, Color.MAGENTA };
public LabelDnd() {
super();
this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
this.setBackground(Color.WHITE);
this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
JPanel basePanel = new JPanel();
basePanel.setLayout(new GridLayout(1, 4, 4, 4));
basePanel.setBackground(Color.CYAN);
MouseAdapter listener = new MouseAdapter() {
Point p = null;
#Override
public void mousePressed(MouseEvent e) {
p = e.getLocationOnScreen();
}
#Override
public void mouseDragged(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
Point l = c.getLocation();
Point here = e.getLocationOnScreen();
c.setLocation(l.x + here.x - p.x, l.y + here.y - p.y);
p = here;
}
};
this.labels = new JLabel[4];
for (int i = 0; i < this.labels.length; i++) {
this.labels[i] = new JLabel(String.valueOf(i), JLabel.CENTER);
this.labels[i].setOpaque(true);
this.labels[i].setPreferredSize(new Dimension(100, 100));
this.labels[i].setBackground(this.colors[i]);
this.labels[i].setForeground(Color.WHITE);
this.labels[i].addMouseListener(listener);
this.labels[i].addMouseMotionListener(listener);
basePanel.add(this.labels[i]);
}
this.add(basePanel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("LabelDnd");
frame.getContentPane().setLayout(new BorderLayout());
LabelDnd panel = new LabelDnd();
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
You are not changing the order that the labels have been added or are being painted in your code. Consider elevating the JLabel to the glasspane when dragging (after removing it from the main container), and then re-adding it to the main container on mouse release.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.*;
import java.util.Comparator;
import java.util.PriorityQueue;
import javax.swing.*;
#SuppressWarnings("serial")
public class LabelDnd extends JPanel {
private static final String X_POS = "x position";
private JLabel[] labels;
private Color[] colors = { Color.BLUE, Color.BLACK, Color.RED, Color.MAGENTA };
public LabelDnd() {
super();
// this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
this.setBackground(Color.WHITE);
this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
JPanel basePanel = new JPanel();
basePanel.setLayout(new GridLayout(1, 4, 4, 4));
basePanel.setBackground(Color.CYAN);
MouseAdapter listener = new MouseAdapter() {
Point loc = null;
Container parentContainer = null;
Container glasspane = null;
JLabel placeHolder = new JLabel("");
private Point glassLocOnScn;
#Override
public void mousePressed(MouseEvent e) {
JComponent selectedLabel = (JComponent) e.getSource();
loc = e.getPoint();
Point currLocOnScn = e.getLocationOnScreen();
parentContainer = selectedLabel.getParent();
JRootPane rootPane = SwingUtilities.getRootPane(selectedLabel);
glasspane = (Container) rootPane.getGlassPane();
glasspane.setVisible(true);
glasspane.setLayout(null);
glassLocOnScn = glasspane.getLocationOnScreen();
Component[] comps = parentContainer.getComponents();
// remove all labels from parent
parentContainer.removeAll();
// add labels back except for selected one
for (Component comp : comps) {
if (comp != selectedLabel) {
parentContainer.add(comp);
} else {
// add placeholder in place of selected component
parentContainer.add(placeHolder);
}
}
selectedLabel.setLocation(currLocOnScn.x - loc.x - glassLocOnScn.x,
currLocOnScn.y - loc.y - glassLocOnScn.y);
glasspane.add(selectedLabel);
glasspane.setVisible(true);
parentContainer.revalidate();
parentContainer.repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
JComponent selectedLabel = (JComponent) e.getSource();
glassLocOnScn = glasspane.getLocationOnScreen();
Point currLocOnScn = e.getLocationOnScreen();
selectedLabel.setLocation(currLocOnScn.x - loc.x - glassLocOnScn.x,
currLocOnScn.y - loc.y - glassLocOnScn.y);
glasspane.repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
JComponent selectedLabel = (JComponent) e.getSource();
if (parentContainer == null || glasspane == null) {
return;
}
// sort the labels based on their x position on screen
PriorityQueue<JComponent> compQueue = new PriorityQueue<JComponent>(
4, new Comparator<JComponent>() {
#Override
public int compare(JComponent o1, JComponent o2) {
// sort of a kludge -- checking a client property that
// holds the x-position
Integer i1 = (Integer) o1.getClientProperty(X_POS);
Integer i2 = (Integer) o2.getClientProperty(X_POS);
return i1.compareTo(i2);
}
});
// sort of a kludge -- putting x position before removing component
// into a client property to associate it with the JLabel
selectedLabel.putClientProperty(X_POS, selectedLabel.getLocationOnScreen().x);
glasspane.remove(selectedLabel);
compQueue.add(selectedLabel);
Component[] comps = parentContainer.getComponents();
for (Component comp : comps) {
JLabel label = (JLabel) comp;
if (!label.getText().trim().isEmpty()) { // if placeholder!
label.putClientProperty(X_POS, label.getLocationOnScreen().x);
compQueue.add(label); // add to queue
}
}
parentContainer.removeAll();
// add back labels sorted by x-position on screen
while (compQueue.size() > 0) {
parentContainer.add(compQueue.remove());
}
parentContainer.revalidate();
parentContainer.repaint();
glasspane.repaint();
}
};
this.labels = new JLabel[4];
for (int i = 0; i < this.labels.length; i++) {
this.labels[i] = new JLabel(String.valueOf(i), JLabel.CENTER);
this.labels[i].setOpaque(true);
this.labels[i].setPreferredSize(new Dimension(100, 100));
this.labels[i].setBackground(this.colors[i]);
this.labels[i].setForeground(Color.WHITE);
this.labels[i].addMouseListener(listener);
this.labels[i].addMouseMotionListener(listener);
basePanel.add(this.labels[i]);
}
this.add(basePanel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("LabelDnd");
frame.getContentPane().setLayout(new BorderLayout());
LabelDnd panel = new LabelDnd();
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Because of z-index of your Swing component. You should use setComponentZOrder to change component's z-index value after you drag.
Please check this link to get more details

How to dynamically add a new customized button?

I am trying to have my interface dynamically generate a customized button when I click a button. I searched several answers like this, but somehow it does not work. Is there any mistake with my current code below?
public class MainWindow {
private JFrame frame;
private JPanel panel;
private JPanel panel_1;
private JPanel panel_2;
private JSplitPane splitPane;
private JButton btnSearch;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 645, 438);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
splitPane = new JSplitPane();
panel.add(splitPane);
panel_1 = new JPanel();
splitPane.setLeftComponent(panel_1);
btnSearch = new JButton("Search");
GridBagConstraints gbc_btnSearch = new GridBagConstraints();
gbc_btnSearch.gridx = 0;
gbc_btnSearch.gridy = 10;
panel_1.add(btnSearch, gbc_btnSearch);
panel_2 = new JPanel();
splitPane.setRightComponent(panel_2);
btnSearch.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
addButton();
}
});
}
protected void addButton() {
MyButton hahaButton = new MyButton("haha");
panel_2.add(hahaButton);
panel_2.add(new JButton());
panel_2.revalidate();
panel_2.repaint();
}
And this is the definition of the MyButton:
public class MyButton extends JButton {
private static final long serialVersionUID = 1L;
private Color circleColor = Color.BLACK;
public MyButton(String label) {
super(label);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension originalSize = super.getPreferredSize();
int gap = (int) (originalSize.height * 0.2);
int x = originalSize.width + gap;
int y = gap;
int diameter = originalSize.height - (gap * 2);
g.setColor(circleColor);
g.fillOval(x, y, diameter, diameter);
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width += size.height;
return size;
}
}
I just tried your sourcecode and it works as expected: everytime I klick the search button on the left side of the split-pane, 2 buttons are added to the panel on the right side of the panel (one with the black filled circle and a button without a label).
What doesn't work for you? I'm using java 1.6 on Mac OSX, but this should work with earlier versions on other platforms as well......
As Dieter Rehbein pointed out, the code you have does compile and run.
However, it was rather sloppy and convoluted, as if you copied and pasted different sources together.
I took a few minutes and cleaned it up some, hope it helps.
public class MainWindow
{
public static void main( String[] args )
{
new MainWindow();
}
public MainWindow()
{
// Create the split pane
JSplitPane jSplitPane = new JSplitPane();
final JPanel leftPanel = new JPanel();
final JPanel rightPanel = new JPanel();
jSplitPane.setLeftComponent( leftPanel );
jSplitPane.setRightComponent( rightPanel );
// Create the button
JButton jButton = new JButton( "Generate" );
leftPanel.add( jButton );
jButton.addMouseListener( new MouseAdapter()
{
#Override
public void mouseClicked( MouseEvent e )
{
addButtons( rightPanel );
}
} );
// Create the panel
JPanel jPanel = new JPanel();
jPanel.setLayout( new BoxLayout( jPanel , BoxLayout.X_AXIS ) );
jPanel.add( jSplitPane );
// Create the frame
JFrame jFrame = new JFrame();
jFrame.setBounds( 100 , 100 , 645 , 438 );
jFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jFrame.getContentPane().add( jPanel , BorderLayout.CENTER );
// Show the frame
jFrame.setVisible( true );
}
private void addButtons( JPanel jPanel )
{
addButton( jPanel , "Default" , null );
addButton( jPanel , "Red" , Color.RED );
addButton( jPanel , "Yellow" , Color.YELLOW );
addButton( jPanel , "Blue" , Color.BLUE );
addButton( jPanel , "Green" , Color.GREEN );
}
protected void addButton( JPanel jPanel , String label , Color color )
{
jPanel.add( new MyButton( label , color ) );
jPanel.revalidate();
jPanel.repaint();
}
public class MyButton extends JButton
{
private static final long serialVersionUID = 1L;
private Color color = null;
public MyButton( String label , Color color )
{
super( label );
this.color = color;
}
#Override
protected void paintComponent( Graphics graphics )
{
super.paintComponent( graphics );
if ( color != null )
{
Dimension dimension = super.getPreferredSize();
int gap = ( int ) ( dimension.height * 0.2 );
int diameter = dimension.height - ( gap * 2 );
graphics.setColor( color );
graphics.fillOval( dimension.width + gap , gap , diameter , diameter );
}
}
#Override
public Dimension getPreferredSize()
{
Dimension size = super.getPreferredSize();
size.width += size.height;
return size;
}
}
}

Categories

Resources