I have a JPanel which contains a JToolbar (including few buttons without text) and a JTable and I need to enable/disable (make internal widgets not clickable). I tried this:
JPanel panel = ....;
for (Component c : panel.getComponents()) c.setEnabled(enabled);
but it doesn't work. Is there a better and more generic solution to enable/disable all internal components in a JPanel?
I have partially solved my problem using JLayer starting from the example here http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html:
layer = new JLayer<JComponent>(myPanel, new BlurLayerUI(false));
.....
((BlurLayerUI)layer.getUI()).blur(...); // switch blur on/off
class BlurLayerUI extends LayerUI<JComponent> {
private BufferedImage mOffscreenImage;
private BufferedImageOp mOperation;
private boolean blur;
public BlurLayerUI(boolean blur) {
this.blur = blur;
float ninth = 1.0f / 9.0f;
float[] blurKernel = {
ninth, ninth, ninth,
ninth, ninth, ninth,
ninth, ninth, ninth
};
mOperation = new ConvolveOp(
new Kernel(3, 3, blurKernel),
ConvolveOp.EDGE_NO_OP, null);
}
public void blur(boolean blur) {
this.blur=blur;
firePropertyChange("blur", 0, 1);
}
#Override
public void paint (Graphics g, JComponent c) {
if (!blur) {
super.paint (g, c);
return;
}
int w = c.getWidth();
int h = c.getHeight();
if (w == 0 || h == 0) {
return;
}
// Only create the offscreen image if the one we have
// is the wrong size.
if (mOffscreenImage == null ||
mOffscreenImage.getWidth() != w ||
mOffscreenImage.getHeight() != h) {
mOffscreenImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
}
Graphics2D ig2 = mOffscreenImage.createGraphics();
ig2.setClip(g.getClip());
super.paint(ig2, c);
ig2.dispose();
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(mOffscreenImage, mOperation, 0, 0);
}
#Override
public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
if ("blur".equals(pce.getPropertyName())) {
l.repaint();
}
}
}
I still have 2 problems:
In the link above events are relative to mouse only. How can I manage the keyboard events?
How can I create a "gray out" effect in place of blur?
It requires a recursive call.
import java.awt.*;
import javax.swing.*;
public class DisableAllInContainer {
public void enableComponents(Container container, boolean enable) {
Component[] components = container.getComponents();
for (Component component : components) {
component.setEnabled(enable);
if (component instanceof Container) {
enableComponents((Container)component, enable);
}
}
}
DisableAllInContainer() {
JPanel gui = new JPanel(new BorderLayout());
final JPanel container = new JPanel(new BorderLayout());
gui.add(container, BorderLayout.CENTER);
JToolBar tb = new JToolBar();
container.add(tb, BorderLayout.NORTH);
for (int ii=0; ii<3; ii++) {
tb.add(new JButton("Button"));
}
JTree tree = new JTree();
tree.setVisibleRowCount(6);
container.add(new JScrollPane(tree), BorderLayout.WEST);
container.add(new JTextArea(5,20), BorderLayout.CENTER);
final JCheckBox enable = new JCheckBox("Enable", true);
enable.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
enableComponents(container, enable.isSelected());
}
});
gui.add(enable, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null, gui);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new DisableAllInContainer();
}
});
}}
I used the following function:
void setPanelEnabled(JPanel panel, Boolean isEnabled) {
panel.setEnabled(isEnabled);
Component[] components = panel.getComponents();
for(int i = 0; i < components.length; i++) {
if(components[i].getClass().getName() == "javax.swing.JPanel") {
setPanelEnabled((JPanel) components[i], isEnabled);
}
components[i].setEnabled(isEnabled);
}
}
you can overlay whole Container / JComponent
GlassPane block by default MouseEvents, but not Keyboard, required consume all keyevents from ToolKit
JLayer (Java7) based on JXLayer (Java6)
can't see reason(s) why not works for you
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
//b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 20));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
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(true);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
//b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(400, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JButton disabledComp = new JButton("Disabled All");
disabledComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Component c : panel.getComponents()) {
c.setEnabled(false);
}
}
});
JButton enabledComp = new JButton("Enabled All");
enabledComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Component c : panel.getComponents()) {
c.setEnabled(true);
}
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
panel2.add(disabledComp);
panel2.add(enabledComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
#Kesavamoorthi
if you want to make it more general:
void setPanelEnabled(java.awt.Container cont, Boolean isEnabled) {
cont.setEnabled(isEnabled);
java.awt.Component[] components = cont.getComponents();
for (int i = 0; i < components.length; i++) {
if (components[i] instanceof java.awt.Container) {
setPanelEnabled((java.awt.Container) components[i], isEnabled);
}
components[i].setEnabled(isEnabled);
}
}
Related
I have a question regarding custom tab components in swing.
The following code will add 3 custom tab components:
public class TabbedExample extends JPanel {
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createUI();
}
}
}
public static void createUI() {
try {
for(LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch(Exception e) {}
JFrame frame = new JFrame("Tab Test");
frame.setMinimumSize(new Dimension(256,200));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new TabbedExample());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public TabbedExample() {
super(new BorderLayout());
JTabbedPane pane = new JTabbedPane();
pane.addTab("tmp", new JTextField());
pane.addTab("tmp", new JTextField());
pane.addTab("tmp", new JTextField());
for(int i = 0; i < 3; i++) {
JPanel tabPanel = new JPanel();
tabPanel.setBackground(new Color(0,0,0,0));
tabPanel.setLayout(new BoxLayout(tabPanel, BoxLayout.X_AXIS));
JTextField textField = new JTextField("Tab " + i);
textField.setOpaque(false);
textField.setBackground(new Color(0,0,0,0));
textField.setBorder(new EmptyBorder(0,0,0,0));
tabPanel.add(label);
tabPanel.add(new JButton(Integer.toString(i)));
pane.setTabComponentAt(i, tabPanel);
}
add(pane, BorderLayout.CENTER);
}
}
the problem now is that the default tab behaviour stops working. normally, when you move your mouse over a tab, it automagically gets highlight by changing the background color. but as soon as the JTextField is hit, the tab most likely registers a mouseExited Event and stops the highlighting of the tab. so the tab will flicker when you move your mouse over the tab.
my question now is:
Is there a way (without implementing a new highlighting mechanism) to highlight the tab, where the custom tabComponent is located?
Here's my attempt:
Using a JLayer to dispatch the MouseMotionEvent from the tabs to the parent JTabbedPane:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class TabbedExample2 extends JPanel {
public static void main(String... args) {
EventQueue.invokeLater(() -> {
createUI();
});
}
public static void createUI() {
try {
for (UIManager.LookAndFeelInfo laf: UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
JFrame frame = new JFrame("Tab Test");
frame.setMinimumSize(new Dimension(256, 200));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new TabbedExample2());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public TabbedExample2() {
super(new BorderLayout());
JTabbedPane pane = new JTabbedPane();
pane.addTab("tmp", new JTextField(16));
pane.addTab("tmp", new JTextField(16));
pane.addTab("tmp", new JTextField(16));
for (int i = 0; i < 3; i++) {
JPanel tabPanel = new JPanel();
tabPanel.setOpaque(false);
//tabPanel.setBackground(new Color(0,0,0,0));
tabPanel.setLayout(new BoxLayout(tabPanel, BoxLayout.X_AXIS));
JTextField textField = new JTextField("Tab " + i);
//textField.setBackground(new Color(0,0,0,0));
//textField.setBorder(new EmptyBorder(0,0,0,0));
//tabPanel.add(label); //???
tabPanel.add(textField);
tabPanel.add(new JButton(Integer.toString(i)));
pane.setTabComponentAt(
i, new JLayer<JPanel>(tabPanel, new DispatchEventLayerUI()));
}
add(pane);
}
}
class DispatchEventLayerUI extends LayerUI<JPanel> {
#Override
public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
//TEST:
//((JLayer) c).setLayerEventMask(
// AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
}
#Override
public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
// //TEST:
// #Override
// protected void processMouseEvent(MouseEvent e, JLayer<? extends JPanel> l) {
// dispatchEvent(e);
// }
#Override
protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends JPanel> l) {
dispatchEvent(e);
}
private void dispatchEvent(MouseEvent e) {
Component src = e.getComponent();
Container tgt = SwingUtilities.getAncestorOfClass(JTabbedPane.class, src);
tgt.dispatchEvent(SwingUtilities.convertMouseEvent(src, e, tgt));
}
}
Hi I've there a little problem: What I want is to delay the appearance of JLabels in a JDialog-Window, in terms of that the first line of JLabels shoud come out and then two seconds later the second line of Jlabels etc.
I've tried something with Windowlistener,the doClick()-Method etc., bu every time the Jdialog revalidates all of its panels AT ONCE and shows them without any delaying!
Please help me(Just copy the code below and try out)!
package footballQuestioner;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
public class attempter {
public static void main(String[] args) throws InterruptedException {
JDialog dialog = new Punkte();
}
}
class Punkte extends JDialog {
private JPanel screenPanel = new JPanel(new GridLayout(4, 1));
private JButton button = new JButton();
private int i = 1;
private class WindowHandler implements WindowListener {
#Override
public void windowActivated(WindowEvent e) {
}
#Override
public void windowClosed(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
}
#Override
public void windowDeactivated(WindowEvent e) {
}
#Override
public void windowDeiconified(WindowEvent e) {
}
#Override
public void windowIconified(WindowEvent e) {
}
#Override
public void windowOpened(WindowEvent e) {
button.doClick(1000);
button.doClick(1000);
button.doClick(1000);
button.doClick(); // here im trying to delay the appearance of the
// JLabels....
}
}
private class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
switch (i) {
case 1:
settingUpPanel(getPanelFromScreenPanel(i), "Right", new Color(
102, 205, 0));
settingUpPanel(getPanelFromScreenPanel(i), "Wrong", Color.RED);
break;
case 2:
settingUpPanel(getPanelFromScreenPanel(i), "Trefferquote",
Color.YELLOW);
break;
case 3:
settingUpPanel(getPanelFromScreenPanel(i), "Ausgezeichnet",
Color.BLUE);
break;
}
System.out.println(i);
i++;
}
}
public Punkte() {
button.addActionListener(new ButtonHandler());
addWindowListener(new WindowHandler());
setModal(true);
setResizable(true);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
settingUpScreenPanel();
add(screenPanel);
setSize(1200, 1000);
centeringWindow();
setVisible(true);
}
private void settingUpScreenPanel() {
JPanel titlePanel = new JPanel(new GridBagLayout());
JPanel rightWrongCountPanel = new JPanel(new GridLayout(1, 2));
JPanel shareOfRightQuestions = new JPanel(new GridBagLayout());
JPanel grade = new JPanel(new GridBagLayout());
settingUpPanel(titlePanel, "Result", Color.BLACK);
// settingUpPanel(rightWrongCountPanel,
// "Right: "+numberOfRightAnsers+"/6",new Color(102,205,0));
// settingUpPanel(rightWrongCountPanel,
// "Wrong: "+(6-numberOfRightAnsers)+"/6", Color.RED);
// settingUpPanel(shareOfRightQuestions,
// "Trefferquote: "+(numberOfRightAnsers*100/6)+"%",Color.YELLOW);
// settingUpPanel(summaSummarum,
// getBufferedImage("footballQuestioner/Strich.png"));
// settingUpPanel(grade,"Aushezeichnet", Color.BLUE);
borderingJPanel(screenPanel, null, null);
titlePanel.setOpaque(false);
rightWrongCountPanel.setOpaque(false);
shareOfRightQuestions.setOpaque(false);
grade.setOpaque(false);
screenPanel.add(titlePanel);
screenPanel.add(rightWrongCountPanel);
screenPanel.add(shareOfRightQuestions);
screenPanel.add(grade);
}
private void settingUpPanel(JComponent panel, String string, Color color) {
Font font = new Font("Rockwell Extra Bold", Font.PLAIN, 65);
JPanel innerPanel = new JPanel(new GridBagLayout());
JLabel label = new JLabel(string);
label.setForeground(color);
label.setFont(font);
innerPanel.add(label);
innerPanel.setOpaque(false);
panel.add(innerPanel);
panel.validate();
panel.repaint();
}
public JPanel getPanelFromScreenPanel(int numberOfPanel) {
JPanel screenPanel = (JPanel) getContentPane().getComponent(0);
JPanel labelPanel = (JPanel) screenPanel.getComponent(numberOfPanel);
return labelPanel;
}
public void centeringWindow() {
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x;
int y;
x = (int) (dimension.getWidth() - getWidth()) / 2;
y = (int) (dimension.getHeight() - getHeight()) / 2;
setLocation(x, y);
}
public void borderingJPanel(JComponent panel, String jPanelname,
String fontStyle) {
Font font = new Font(fontStyle, Font.BOLD + Font.ITALIC, 12);
if (jPanelname != null) {
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY,
Color.WHITE), jPanelname,
TitledBorder.DEFAULT_JUSTIFICATION,
TitledBorder.DEFAULT_POSITION, font));
} else if (jPanelname == null || fontStyle == null) {
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(EtchedBorder.LOWERED, Color.BLACK,
Color.WHITE)));
}
panel.setOpaque(false);
}
}
This is a really good use case for javax.swing.Timer...
This will allow you to schedule a callback, at a regular interval with which you can perform an action, safely on the UI.
private class WindowHandler extends WindowAdapter {
#Override
public void windowOpened(WindowEvent e) {
System.out.println("...");
Timer timer = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel panel = getPanelFromScreenPanel(1);
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index = 0; index < 100; index++) {
panel.add(new JLabel(Integer.toString(index)), gbc);
}
panel.revalidate();
}
});
timer.start();
timer.setRepeats(false);
}
}
Now, if you wanted to do a series of actions, separated by the interval, you could use a counter to determine the number of "ticks" that have occurred and take appropriate action...
private class WindowHandler extends WindowAdapter {
#Override
public void windowOpened(WindowEvent e) {
System.out.println("...");
Timer timer = new Timer(2000, new ActionListener() {
private int counter = 0;
private int maxActions = 10;
#Override
public void actionPerformed(ActionEvent e) {
switch (counter) {
case 0:
// Action for case 0...
break;
case 1:
// Action for case 1...
break;
.
.
.
}
counter++;
if (counter >= maxActions) {
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
}
Take a look at How to use Swing Timers for more details
Good morning. I want to write a program that scale up a filledgraphic with the help of JSlider. When ActPanel and Contour were inner classes of Lab4, they at least showed themselves on a JFrame. But there was a huge problem with passing Radius and repainting. I refrained from using inner classes, but it gave me no more ActPanel and Contour on the screen.
Here is code's most important part
class ActPanel extends JPanel implements ChangeListener {
public Contour cont;
public ActPanel(Contour contour) {
super(new FlowLayout());
cont = contour;
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 250, 50);
slider.addChangeListener(this);
JButton button = new JButton("display mark");
}
public void stateChanged(ChangeEvent e) {
if (e.getSource() instanceof JSlider) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
int R = (int)source.getValue();
cont.setR(R);
cont.repaint();
}
}
}
}
class Contour extends JPanel {
private static final int pointCount = 9;
public void paintComponent(Graphics gfx) {
super.paintComponent(gfx);
Graphics2D g = (Graphics2D) gfx;
GeneralPath fpolygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, pointCount);
fpolygon.moveTo(Float.valueOf((float)R+250), Float.valueOf(250.0f));
fpolygon.lineTo(Float.valueOf(250.0f), Float.valueOf(250.0f));
//some drawing
}
private int R;
public void setR(int R) {
this.R = R;
}
public int getR() {
return R;
}
}
public class Lab4 {
private static void addComponentsToPane(Container pane) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
Contour cont = new Contour();
ActPanel bottom = new ActPanel(cont);
pane.add(bottom, BorderLayout.PAGE_END);
cont.setPreferredSize(new Dimension(500,500));
pane.add(cont, BorderLayout.LINE_END);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Lab4");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String [] arg) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
And that's a full version
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;
class ActPanel extends JPanel implements ChangeListener {
public Contour cont;
public ActPanel(Contour contour) {
super(new FlowLayout());
cont = contour;
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 250, 50);
slider.addChangeListener(this);
JButton button = new JButton("display mark");
}
public void stateChanged(ChangeEvent e) {
if (e.getSource() instanceof JSlider) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
int R = (int)source.getValue();
cont.setR(R);
cont.repaint();
}
}
}
}
class Contour extends JPanel {
private static final int pointCount = 9;
public void paintComponent(Graphics gfx) {
super.paintComponent(gfx);
double kappa = 0.5522847498;
Graphics2D g = (Graphics2D) gfx;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
GeneralPath fpolygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, pointCount);
fpolygon.moveTo(Float.valueOf((float)R+250), Float.valueOf(250.0f));
fpolygon.lineTo(Float.valueOf(250.0f), Float.valueOf(250.0f));
fpolygon.lineTo(Float.valueOf(250.0f), Float.valueOf((float)250-R/2));
fpolygon.curveTo(
Float.valueOf((float)((-R/2)*kappa+250)),Float.valueOf((float)(-R/2)+250),
Float.valueOf((float)(-R/2)+250),Float.valueOf((float)((-R/2)*kappa)+250),
Float.valueOf((float)-R/2+250), Float.valueOf(250.0f));
fpolygon.lineTo(Float.valueOf((float)-R+250), Float.valueOf(250.0f));
fpolygon.lineTo(Float.valueOf((float)-R+250), Float.valueOf((float)R+250));
fpolygon.lineTo(Float.valueOf(250.0f), Float.valueOf((float)R+250));
fpolygon.lineTo(Float.valueOf(250.0f), Float.valueOf((float)R/2+250));
fpolygon.lineTo(Float.valueOf((float)R+250), Float.valueOf(250.0f));
fpolygon.closePath();
g.setPaint(Color.red);
g.fill(fpolygon);
g.setPaint(Color.black);
g.draw(fpolygon);
}
private int R;
public void setR(int R) {
this.R = R;
}
public int getR() {
return R;
}
}
public class Lab4 {
private static void addComponentsToPane(Container pane) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
Contour cont = new Contour();
ActPanel bottom = new ActPanel(cont);
pane.add(bottom, BorderLayout.PAGE_END);
JList<Integer> xList = new JList<Integer>(new Integer[] {4,2,5,1,-5,-1,-4});
pane.add(xList, BorderLayout.LINE_START);
JPanel yPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
yPanel.add(new Label("x\\y"));
yPanel.add(new JCheckBox("5"));
yPanel.add(new JCheckBox("1"));
yPanel.add(new JCheckBox("-5"));
yPanel.add(new JCheckBox("2"));
yPanel.add(new JCheckBox("-5"));
yPanel.add(new JCheckBox("-1"));
yPanel.add(new JCheckBox("4"));
pane.add(yPanel, BorderLayout.PAGE_START);
cont.setPreferredSize(new Dimension(500,500));
pane.add(cont, BorderLayout.LINE_END);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Lab4");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String [] arg) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
You never add the any component to the ActPanel:
public ActPanel(Contour contour) {
super(new FlowLayout());
...
// you're missing the following lines:
this.add(slider);
this.add(button);
So it is in the frame, but empty.
The Contour panel is also in the frame. Add these lines to it, and you'll see it:
public Contour() {
setBackground(Color.BLUE);
}
I am using Metal L&F. I want to make a JComboBox, that has only 1 pixel border. This not a problem, as long as the cb is editable. This corresponds to the first cb in the picture named "Editable".
cb.setEditable(true);
((JTextComponent) (cb.getEditor().getEditorComponent())).setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, COLOR));
But when I do cb.setEditable(false), an additional border occurs inside the box (changed to red in the picture "Dropdown", you see the original color in the picture named "Fixed"). Although I tried to set the border and I also tried to use my own CellRenderer, the border still gets painted. It seems to me, that the unwanted border does not come from the CellRenderer. When I try to manipulate the border from the cb itself (see comment //), it only adds/removes an additional outer border. The editorComponent also seems not to be responsible to me.
cb.setRenderer(new CbCellRenderer());
//cb.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, COLOR));
//cb.setBorder(BorderFactory.createEmptyBorder());
class CbCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
renderer.setBorder(BorderFactory.createEmptyBorder());
return renderer;
}
}
I also tried out some UI variables like the ones below without taking affect on this border.
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
UIManager.put("ComboBox.selectionForeground", Color.green);
UIManager.put("ComboBox.disabledBackground", Color.green);
...
Image: http://upload.mtmayr.com/dropdown_frame.png (link broken)
Complete code for testing:
import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboPopup;
public class ComboTest {
private Vector<String> listSomeString = new Vector<String>();
private JComboBox editableComboBox = new JComboBox(listSomeString);
private JComboBox nonEditableComboBox = new JComboBox(listSomeString);
private JFrame frame;
public final static Color COLOR_BORDER = new Color(122, 138, 153);
public ComboTest() {
listSomeString.add("row 1");
listSomeString.add("row 2");
listSomeString.add("row 3");
listSomeString.add("row 4");
editableComboBox.setEditable(true);
editableComboBox.setBackground(Color.white);
Object child = editableComboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup) child;
JList list = popup.getList();
list.setBackground(Color.white);
list.setSelectionBackground(Color.red);
JTextField tf = ((JTextField) editableComboBox.getEditor().getEditorComponent());
tf.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, COLOR_BORDER));
nonEditableComboBox.setEditable(false);
nonEditableComboBox.setBorder(BorderFactory.createEmptyBorder());
nonEditableComboBox.setBackground(Color.white);
Object childNonEditable = nonEditableComboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popupNonEditable = (BasicComboPopup) childNonEditable;
JList listNonEditable = popupNonEditable.getList();
listNonEditable.setBackground(Color.white);
listNonEditable.setSelectionBackground(Color.red);
frame = new JFrame();
frame.setLayout(new GridLayout(0, 1, 10, 10));
frame.add(editableComboBox);
frame.add(nonEditableComboBox);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ComboTest ct = new ComboTest();
}
});
}
}
How about override MetalComboBoxUI#paintCurrentValueBackground(...)
using JDK 1.7.0_17, Windows 7
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;
public class ComboBoxUIDemo {
private static Color BORDER = Color.GRAY;
public JComponent makeUI() {
//UIManager.put("ComboBox.foreground", Color.WHITE);
//UIManager.put("ComboBox.background", Color.BLACK);
//UIManager.put("ComboBox.selectionForeground", Color.CYAN);
//UIManager.put("ComboBox.selectionBackground", Color.BLACK);
//UIManager.put("ComboBox.buttonDarkShadow", Color.WHITE);
//UIManager.put("ComboBox.buttonBackground", Color.GRAY);
//UIManager.put("ComboBox.buttonHighlight", Color.WHITE);
//UIManager.put("ComboBox.buttonShadow", Color.WHITE);
//UIManager.put("ComboBox.editorBorder", BorderFactory.createLineBorder(Color.RED));
Box box = Box.createVerticalBox();
UIManager.put("ComboBox.border", BorderFactory.createEmptyBorder());
for(int i=0; i<2; i++) { // Defalut
JComboBox<String> cb = new JComboBox<>(makeModel());
if(i%2==0) setEditable(cb);
setPopupBorder(cb);
box.add(cb);
box.add(Box.createVerticalStrut(10));
}
{
// Override MetalComboBoxUI#paintCurrentValueBackground(...)
JComboBox<String> cb = new JComboBox<>(makeModel());
cb.setUI(new MetalComboBoxUI() {
#Override public void paintCurrentValueBackground(
Graphics g, Rectangle bounds, boolean hasFocus) {
//if (MetalLookAndFeel.usingOcean()) {
if(MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme) {
g.setColor(MetalLookAndFeel.getControlDarkShadow());
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
//COMMENTOUT>>>
//g.setColor(MetalLookAndFeel.getControlShadow());
//g.drawRect(bounds.x + 1, bounds.y + 1, bounds.width - 2,
// bounds.height - 3);
//<<<COMMENTOUT
if (hasFocus && !isPopupVisible(comboBox) && arrowButton != null) {
g.setColor(listBox.getSelectionBackground());
Insets buttonInsets = arrowButton.getInsets();
if (buttonInsets.top > 2) {
g.fillRect(bounds.x + 2, bounds.y + 2, bounds.width - 3,
buttonInsets.top - 2);
}
if (buttonInsets.bottom > 2) {
g.fillRect(bounds.x + 2, bounds.y + bounds.height -
buttonInsets.bottom, bounds.width - 3,
buttonInsets.bottom - 2);
}
}
} else if (g == null || bounds == null) {
throw new NullPointerException(
"Must supply a non-null Graphics and Rectangle");
}
}
});
setPopupBorder(cb);
box.add(cb);
box.add(Box.createVerticalStrut(10));
}
UIManager.put("ComboBox.border", BorderFactory.createLineBorder(BORDER));
for(int i=0; i<2; i++) { // BasicComboBoxUI
JComboBox<String> cb = new JComboBox<>(makeModel());
if(i%2==0) setEditable(cb);
cb.setUI(new BasicComboBoxUI());
setPopupBorder(cb);
box.add(cb);
box.add(Box.createVerticalStrut(10));
}
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createEmptyBorder(10,20,10,20));
p.add(box, BorderLayout.NORTH);
return p;
}
private static void setEditable(JComboBox cb) {
cb.setEditable(true);
ComboBoxEditor editor = cb.getEditor();
Component c = editor.getEditorComponent();
if(c instanceof JTextField) {
JTextField tf = (JTextField)c;
tf.setBorder(BorderFactory.createMatteBorder(1,1,1,0,BORDER));
}
}
private static void setPopupBorder(JComboBox cb) {
Object o = cb.getAccessibleContext().getAccessibleChild(0);
JComponent c = (JComponent)o;
c.setBorder(BorderFactory.createMatteBorder(0,1,1,1,BORDER));
}
private static DefaultComboBoxModel<String> makeModel() {
DefaultComboBoxModel<String> m = new DefaultComboBoxModel<>();
m.addElement("1234");
m.addElement("5555555555555555555555");
m.addElement("6789000000000");
return m;
}
public static void main(String[] args) {
// OceanTheme theme = new OceanTheme() {
// #Override protected ColorUIResource getSecondary2() {
// return new ColorUIResource(Color.RED);
// }
// };
// MetalLookAndFeel.setCurrentTheme(theme);
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ComboBoxUIDemo().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
not able to ...., every have got the same Borders, there must be another issue, 1st and 2nd. are editable JComboBoxes
for better help sooner post an SSCCE, short, runnable, compilable, just about two JComboBoxes, Native OS, compiled in JDK, runned in JRE
WinXP Java6
Win7 Java7
Win7 Java6
Win8 Java6
Win8 Java7
from code
import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalComboBoxButton;
public class MyComboBox {
private Vector<String> listSomeString = new Vector<String>();
private JComboBox someComboBox = new JComboBox(listSomeString);
private JComboBox editableComboBox = new JComboBox(listSomeString);
private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
private JFrame frame;
public MyComboBox() {
listSomeString.add("-");
listSomeString.add("Snowboarding");
listSomeString.add("Rowing");
listSomeString.add("Knitting");
listSomeString.add("Speed reading");
//
someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
someComboBox.setEditable(true);
someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
//
editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
editableComboBox.setEditable(true);
JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
text.setBackground(Color.YELLOW);
JComboBox coloredArrowsCombo = editableComboBox;
Component[] comp = coloredArrowsCombo.getComponents();
for (int i = 0; i < comp.length; i++) {
if (comp[i] instanceof MetalComboBoxButton) {
MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
coloredArrowsButton.setBackground(null);
break;
}
}
//
non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
//
frame = new JFrame();
frame.setLayout(new GridLayout(0, 1, 10, 10));
frame.add(someComboBox);
frame.add(editableComboBox);
frame.add(non_EditableComboBox);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow));
UIManager.put("JTextField.background", new ColorUIResource(Color.yellow));
UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyComboBox aCTF = new MyComboBox();
}
});
}
}
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