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();
}
});
}
}
Related
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);
}
}}
I've got (again) a problem: i got a jbutton with an image on background, but when i want to put some text on it, it will apears on the right side of background, not in button, but aside...
Here is working code, you must only link some image :)
package program;
import java.awt.Image;
import java.awt.Insets;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class Program {
private static JFrame frame;
private static JPanel panel;
private static JButton button;
private static Image buttonImage;
private static ImageIcon buttonIcon;
public static void main(String[] args) {
frame = new JFrame("Program");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
frame.add(panel);
frame.pack();
frame.setVisible(true);
frame.setSize(200,100);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
String imgUrl = "images/";
try {
buttonImage = ImageIO.read(new File(imgUrl+"img.png"));
} catch (IOException e) {
Logger.getLogger(Program.class.getName()).log(Level.SEVERE, null, e);
}
buttonIcon = new ImageIcon(buttonImage);
button = new JButton("TEST", buttonIcon);
panel.add(button);
button.setMargin(new Insets(0, 0, 0, 0));
button.setBounds(0, 0, 146, 67);
button.setOpaque(false);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
}
}
Here are 4 ways to display text on an image:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class LabelImageText extends JPanel
{
public LabelImageText()
{
JLabel label1 = new JLabel( new ColorIcon(Color.ORANGE, 100, 100) );
label1.setText( "Easy Way" );
label1.setHorizontalTextPosition(JLabel.CENTER);
label1.setVerticalTextPosition(JLabel.CENTER);
add( label1 );
//
JLabel label2 = new JLabel( new ColorIcon(Color.YELLOW, 200, 150) );
label2.setLayout( new BoxLayout(label2, BoxLayout.Y_AXIS) );
add( label2 );
JLabel text = new JLabel( "More Control" );
text.setAlignmentX(JLabel.CENTER_ALIGNMENT);
label2.add( Box.createVerticalGlue() );
label2.add( text );
label2.add( Box.createVerticalStrut(10) );
//
JLabel label3 = new JLabel( new ColorIcon(Color.GREEN, 200, 150) );
label3.setLayout( new GridBagLayout() );
add( label3 );
JLabel text3 = new JLabel();
text3.setText("<html><center>Text<br>over<br>Image<center></html>");
text3.setLocation(20, 20);
text3.setSize(text3.getPreferredSize());
label3.add( text3 );
//
JLabel label4 = new JLabel( new ColorIcon(Color.CYAN, 200, 150) );
add( label4 );
JTextPane textPane = new JTextPane();
textPane.setText("Add some text that will wrap at your preferred width");
textPane.setEditable( false );
textPane.setOpaque(false);
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
StyledDocument doc = textPane.getStyledDocument();
doc.setParagraphAttributes(0, doc.getLength(), center, false);
textPane.setBounds(20, 20, 75, 100);
label4.add( textPane );
}
public static class ColorIcon implements Icon
{
private Color color;
private int width;
private int height;
public ColorIcon(Color color, int width, int height)
{
this.color = color;
this.width = width;
this.height = height;
}
public int getIconWidth()
{
return width;
}
public int getIconHeight()
{
return height;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.setColor(color);
g.fillRect(x, y, width, height);
}
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("LabelImageText");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new LabelImageText() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
you never set the background,you'v set the icon of the button
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StringTest extends JFrame
implements ActionListener
{
private JTextField input, result;
private int i;
public StringTest()
{
super("String test");
i=0;
Box box1 = Box.createVerticalBox();
box1.add(new JLabel(" Input:"));
box1.add(Box.createVerticalStrut(10));
box1.add(new JLabel("Result:"));
input = new JTextField(40);
input.setBackground(Color.WHITE);
input.addActionListener(this);
input.selectAll();
result = new JTextField(40);
result.setBackground(Color.YELLOW);
result.setEditable(false);
Box box2 = Box.createVerticalBox();
box2.add(input);
box2.add(Box.createVerticalStrut(10));
box2.add(result);
Box box3 = Box.createHorizontalBox();
box3.add(box1);
box3.add(box2);
Box box4 = Box.createVerticalBox();
JButton new_game = new JButton("NEW GAME");
JLabel game_title =new JLabel("***Welcome to Hangman Game***");
box4.add(game_title);
box4.add(box3);
box4.add(Box.createVerticalStrut(10));
box4.add(box3);
box4.add(Box.createVerticalStrut(10));
box4.add(new_game);
new_game.setAlignmentX(Component.CENTER_ALIGNMENT);
Container c = getContentPane();
c.setLayout(new FlowLayout());
c.add(box4);
//c.add(box2);
// c.add(ok_button);c.add(ok1_button);
input.requestFocus();
}
public void actionPerformed(ActionEvent e)
{
String str = input.getText();
result.setText(str);
if (i%2==0)
result.setBackground(Color.WHITE);
else
result.setBackground(Color.YELLOW);
input.selectAll();
}
public static void main(String[] args)
{
StringTest window = new StringTest();
window.setBounds(100, 100, 600, 100);
window.setDefaultCloseOperation(EXIT_ON_CLOSE);
window.setVisible(true);
}
}
I am trying to get a JPanel to appear inside of another JPanel. Currently, the JPanel is in an external JFrame and loads with my other JFrame. I want the JPanel to be inside the other JPanel so the program does not open two different windows.
Here is a picture:
The small JPanel with the text logs I want inside of the main game frame. I've tried adding the panel to the panel, panel.add(othePanel). I've tried adding it the JFrame, frame.add(otherPanel). It just overwrites everything else and gives it a black background.
How can I add the panel, resize, and move it?
Edits:
That is where I want the chatbox to be.
Class code:
Left out top of class.
public static JPanel panel;
public static JTextArea textArea = new JTextArea(5, 30);
public static JTextField userInputField = new JTextField(30);
public static void write(String message) {
Chatbox.textArea.append("[Game]: " + message + "\n");
Chatbox.textArea.setCaretPosition(Chatbox.textArea.getDocument()
.getLength());
Chatbox.userInputField.setText("");
}
public Chatbox() {
panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.BLACK);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(380, 100));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
scrollPane
.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
userInputField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String fromUser = userInputField.getText();
if (fromUser != null) {
textArea.append(Frame.username + ":" + fromUser + "\n");
textArea.setCaretPosition(textArea.getDocument()
.getLength());
userInputField.setText("");
}
}
});
panel.add(userInputField, SwingConstants.CENTER);
panel.add(scrollPane, SwingConstants.CENTER);
//JFrame frame = new JFrame();
//frame.add(panel);
//frame.setSize(400, 170);
//frame.setVisible(true);
}
Main frame class:
public Frame() {
frame.getContentPane().remove(loginPanel);
frame.repaint();
String capName = capitalizeString(Frame.username);
name = new JLabel(capName);
new EnemyHealth("enemyhealth10.png");
new Health("health10.png");
new LoadRedCharacter("goingdown.gif");
new Spellbook();
new LoadMobs();
new LoadItems();
new Background();
new Inventory();
new ChatboxInterface();
frame.setBackground(Color.black);
Frame.redHealthLabel.setFont(new Font("Serif", Font.PLAIN, 20));
ticks.setFont(new Font("Serif", Font.PLAIN, 20));
ticks.setForeground(Color.yellow);
Frame.redHealthLabel.setForeground(Color.black);
// Inventory slots
panel.add(slot1);
panel.add(name);
name.setFont(new Font("Serif", Font.PLAIN, 20));
name.setForeground(Color.white);
panel.add(enemyHealthLabel);
panel.add(redHealthLabel);
panel.add(fireSpellBookLabel);
panel.add(iceSpellBookLabel);
panel.add(spiderLabel);
panel.add(appleLabel);
panel.add(fireMagicLabel);
panel.add(swordLabel);
// Character
panel.add(redCharacterLabel);
// Interface
panel.add(inventoryLabel);
panel.add(chatboxLabel);
// Background
panel.add(backgroundLabel);
frame.setContentPane(panel);
frame.getContentPane().invalidate();
frame.getContentPane().validate();
frame.getContentPane().repaint();
//I WOULD LIKE THE LOADING OF THE PANEL SOMEWHERE IN THIS CONSTRUCTOR.
new ResetEntities();
frame.repaint();
panel.setLayout(null);
Run.loadKeyListener();
Player.px = Connect.x;
Player.py = Connect.y;
new Mouse();
TextualMenu.rect = new Rectangle(Frame.inventoryLabel.getX() + 80,
Frame.inventoryLabel.getY() + 100,
Frame.inventoryLabel.getWidth(),
Frame.inventoryLabel.getHeight());
Player.startMessage();
}
Don't use static variables.
Don't use a null layout.
Use appropriate layout managers. Maybe the main panel uses a BorderLayout. Then you add your main component to the CENTER and a second panel to the EAST. The second panel can also use a BorderLayout. You can then add the two components to the NORTH, CENTER or SOUTH as you require.
For example, using a custom Border:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.RadialGradientPaint;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
#SuppressWarnings("serial")
public class FrameEg extends JPanel {
public static final String FRAME_URL_PATH = "http://th02.deviantart.net/"
+ "fs70/PRE/i/2010/199/1/0/Just_Frames_5_by_ScrapBee.png";
public static final int INSET_GAP = 120;
private BufferedImage frameImg;
private BufferedImage smlFrameImg;
public FrameEg() {
try {
URL frameUrl = new URL(FRAME_URL_PATH);
frameImg = ImageIO.read(frameUrl);
final int smlFrameWidth = frameImg.getWidth() / 2;
final int smlFrameHeight = frameImg.getHeight() / 2;
smlFrameImg = new BufferedImage(smlFrameWidth, smlFrameHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics g = smlFrameImg.getGraphics();
g.drawImage(frameImg, 0, 0, smlFrameWidth, smlFrameHeight, null);
g.dispose();
int top = INSET_GAP;
int left = top;
int bottom = top;
int right = left;
Insets insets = new Insets(top, left, bottom, right);
MyBorder myBorder = new MyBorder(frameImg, insets);
JTextArea textArea = new JTextArea(50, 60);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
for (int i = 0; i < 300; i++) {
textArea.append("Hello world! How is it going? ");
}
setLayout(new BorderLayout(1, 1));
setBackground(Color.black);
Dimension prefSize = new Dimension(frameImg.getWidth(),
frameImg.getHeight());
JPanel centerPanel = new MyPanel(prefSize);
centerPanel.setBorder(myBorder);
centerPanel.setLayout(new BorderLayout(1, 1));
centerPanel.add(new JScrollPane(textArea), BorderLayout.CENTER);
MyPanel rightUpperPanel = new MyPanel(new Dimension(smlFrameWidth,
smlFrameHeight));
MyPanel rightLowerPanel = new MyPanel(new Dimension(smlFrameWidth,
smlFrameHeight));
top = top / 2;
left = left / 2;
bottom = bottom / 2;
right = right / 2;
Insets smlInsets = new Insets(top, left, bottom, right);
rightUpperPanel.setBorder(new MyBorder(smlFrameImg, smlInsets));
rightUpperPanel.setLayout(new BorderLayout());
rightLowerPanel.setBorder(new MyBorder(smlFrameImg, smlInsets));
rightLowerPanel.setBackgroundImg(createBackgroundImg(rightLowerPanel
.getPreferredSize()));
JTextArea ruTextArea1 = new JTextArea(textArea.getDocument());
ruTextArea1.setWrapStyleWord(true);
ruTextArea1.setLineWrap(true);
rightUpperPanel.add(new JScrollPane(ruTextArea1), BorderLayout.CENTER);
JPanel rightPanel = new JPanel(new GridLayout(0, 1, 1, 1));
rightPanel.add(rightUpperPanel);
rightPanel.add(rightLowerPanel);
rightPanel.setOpaque(false);
add(centerPanel, BorderLayout.CENTER);
add(rightPanel, BorderLayout.EAST);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private BufferedImage createBackgroundImg(Dimension preferredSize) {
BufferedImage img = new BufferedImage(preferredSize.width,
preferredSize.height, BufferedImage.TYPE_INT_ARGB);
Point2D center = new Point2D.Float(img.getWidth()/2, img.getHeight()/2);
float radius = img.getWidth() / 2;
float[] dist = {0.0f, 1.0f};
Color centerColor = new Color(100, 100, 50);
Color outerColor = new Color(25, 25, 0);
Color[] colors = {centerColor , outerColor };
RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors);
Graphics2D g2 = img.createGraphics();
g2.setPaint(paint);
g2.fillRect(0, 0, img.getWidth(), img.getHeight());
g2.dispose();
return img;
}
private static void createAndShowGui() {
FrameEg mainPanel = new FrameEg();
JFrame frame = new JFrame("FrameEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MyPanel extends JPanel {
private Dimension prefSize;
private BufferedImage backgroundImg;
public MyPanel(Dimension prefSize) {
this.prefSize = prefSize;
}
public void setBackgroundImg(BufferedImage background) {
this.backgroundImg = background;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
return prefSize;
}
}
#SuppressWarnings("serial")
class MyBorder extends AbstractBorder {
private BufferedImage borderImg;
private Insets insets;
public MyBorder(BufferedImage borderImg, Insets insets) {
this.borderImg = borderImg;
this.insets = insets;
}
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
g.drawImage(borderImg, 0, 0, c);
}
#Override
public Insets getBorderInsets(Component c) {
return insets;
}
}
Which would look like:
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