displaying images in JComboBox - java

i need to display a image in JComboBox

Just add an Icon to the model instead of a String:
import java.awt.*;
import javax.swing.*;
public class ComboBoxIcon extends JFrame
{
JComboBox comboBox;
public ComboBoxIcon()
{
Object[] items =
{
new ImageIcon("about16.gif"),
new ImageIcon("add16.gif"),
new ImageIcon("copy16.gif")
};
comboBox = new JComboBox( items );
getContentPane().add( comboBox, BorderLayout.NORTH );
}
public static void main(String[] args)
{
JFrame frame = new ComboBoxIcon();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}

Take a look at this example that appears to do what you want.
http://www.java2s.com/Code/Java/Swing-JFC/CustomComboBoxwithImage.htm
What you are looking for is a custom renderer for the JComboBox. A renderer is simply a JComponent, so if you can create a component (JPanel with the necessary items contained), then you can create almost any result that you can think of). You can even override the paint method if using standard JComponents are not enough for you.

Related

JSplitPane: Possible to have one side empty/transparent to see lower layer underneath?

My aim is to have a bottom layer which will be a large JPanel, and a layer above that which features only one half of a JSplitPane. The intent is that I am able to expand and contract the Split Pane while the Panel beneath doesn't get resized - only covered up.
In my research, the only similar thing I found was this question:
JSplitPane in JLayeredPane
The poster's goal is the same as mine, but they never received an answer.
Is this possible?
Possible to have one side empty/transparent to see lower layer underneath?
If you want to see the background of a parent component, then you need to make the child component transparent.
So, in this case you need to make the split pane transparent. You also need add a transparent component to the split pane.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SplitPaneTransparent extends JPanel
{
public SplitPaneTransparent()
{
setLayout( new BorderLayout() );
setBackground( Color.YELLOW );
JSplitPane splitPane = new JSplitPane();
splitPane.setOpaque( false );
add( splitPane );
JPanel left = new JPanel();
left.setBackground( Color.RED );
splitPane.setLeftComponent( left );
splitPane.setRightComponent( Box.createHorizontalStrut(0) );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SplitPane Transparent");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SplitPaneTransparent());
frame.setSize(300, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}

JComboBox Dropdown Menu Not Obeying AlwaysOnTop

I have an always-on-top window that I want to remain above all other windows. Using setAlwaysOnTop(true) seems to work for most purposes, but fails when it comes to JComboBox dropdown menus. Is there any way to prevent this from happening? Attached below is a SSCCE and picture of the undesired functionality.
EDIT: Not sure if the behavior is OS-dependent, but I'm noticing the issue on Windows 7 using Java 7. On top is supported on this OS.
EDIT 2: Seems that JPopupMenu has an override on alwaysOnTop() to return true. This is the source of the problem, since on-top components do not have a defined order in how they appear on top of each other (OS-dependent). Worse still, the method is package private. Quite problematic...
Undesired Behavior:
SSCCE:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JTextField;
public class OnTopTest
{
public static void main( String[] args )
{
new OnTopTest();
}
public OnTopTest()
{
JDialog onTop = new OnTopWindow();
JDialog other = new OtherWindow();
System.out.println("IS ON TOP SUPPORTED? " + onTop.isAlwaysOnTopSupported());
other.setVisible( true );
onTop.setVisible( true );
}
private class OnTopWindow extends JDialog
{
public OnTopWindow()
{
setLayout( new BorderLayout() );
JButton button = new JButton("Button");
add( button, BorderLayout.CENTER );
setSize( 100, 100 );
setAlwaysOnTop( true );
}
}
private class OtherWindow extends JDialog
{
public OtherWindow()
{
setLayout( new BorderLayout() );
JTextField textField = new JTextField("Text");
add( textField, BorderLayout.NORTH);
JButton button = new JButton("Button");
add( button, BorderLayout.CENTER );
JComboBox comboBox = new JComboBox( new Object[] {"Item1", "Item2", "Item3"} );
add( comboBox, BorderLayout.SOUTH );
setSize( 200, 200 );
}
}
}
I'm pretty sure this is handled by the Operating System and that Java cannot force the dropdown to not overlap the other window, as searching for this without specifying Java reported the same behaviour in many different languages.
You can test with a JMenu to confirm, but I'm sure it will also happen as menus and some other controls (like dropdowns) will (by necessity) show above any other window.

How to add a picture onto JTabbedPane - on a null panel layout?

I want to implement a 200 * 200 picture onto my JTabbed Pane layout from the src folder.
My issue is that nothing is showing- no error no exception and no picture.
I dont think I have to declare the directory and set as a private as its already included in the src folder.
import java.awt.*;
import javax.swing.*;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JFrame;
public class Example1
extends JFrame
{
private JTabbedPane tabbedPane;
private JPanel panel1;
public Example1()
{
// NOTE: to reduce the amount of code in this example, it uses
// panels with a NULL layout. This is NOT suitable for
// production code since it may not display correctly for
// a look-and-feel.
setTitle( "Program" );
setSize( 800, 400 );
setBackground( Color.gray );
JPanel topPanel = new JPanel();
topPanel.setLayout( new BorderLayout() );
getContentPane().add( topPanel );
// Create the tab pages
createPage1();
// Create a tabbed pane
tabbedPane = new JTabbedPane();
tabbedPane.addTab( "Tab Page", panel1 );
topPanel.add( tabbedPane, BorderLayout.CENTER );
}
public void createPage1()
{
panel1 = new JPanel();
panel1.setLayout( null );
ImageIcon pic = new ImageIcon("test.png");
JLabel label = new JLabel (pic);
panel1.add(label);
label.setVisible (true);
label.setBounds( 200, 200, 200, 400 );
}
// Main method to get things started
public static void main( String args[] )
{
// Create an instance of the test application
Example1 mainFrame = new Example1();
mainFrame.setVisible( true );
}
}
If you want me to provide more info please ask for it.
Don't use a null layout (and get ride of the setBounds()) on your panel.
The panel doesn't have a preferred size so Swing thinks there is nothing to paint.
ImageIcon doesn't display any error if an image cannot be found - make sure the image is located in the application directory of the application
Re using a null layout, from the docs
Although it is possible to do without a layout manager, you should use a layout manager if at all possible.

How to Dynamically Add JButton to JPanel?

In NetBeans, I have used the GUI editor to make a JFrame and I've put a JPanel in the frame.
At the moment, I'm trying to make a new button in the panel when the class constructs.
This is the code I have, but I can't seem to get it to work.
(The first line makes the button, the other lines try to show it.)
this.jPanel2.add(new JButton("Test"),BorderLayout.NORTH);
this.jPanel2.validate();
this.jPanel2.revalidate();
this.jPanel2.repaint();
this.jPanel2.setVisible(true);
this.revalidate();
this.setVisible(true);
this.repaint();
I've been googling all night, but can't seem to get it to work.
Some times when you don't see a button it is a layout manager issue (as in you aren't setting the right properties for the layout manager). You can test this by disabling it:
this.jPanel2.setLayoutManager(null);
And setting bounds for the button (JButton.setBounds()).
If the above fixes your problem, then you need to look into the requirements set by the LayoutManager you are using (see also the answer by Robin).
All the calls to validate(), revalidate() and repaint() are not needed to do this.
Normally the add call is sufficient.
Note: a BorderLayout can only contain one component in each location. So if you add another component in the NORTH location, your button will not be visible.
Second note: by default a JPanel does not have a BorderLayout but a FlowLayout. Have you set a BorderLayout on that specific panel ? Otherwise the BorderLayout#NORTH constraint is incorrect
All the validate,revalidate,repaint calls can be removed
Edit
It seems some sort of validation is needed after all. I was under the impression that Swing should be smart enough to listen for the event when something is added to a Container, and update whatever is necessary (a bit similar to updating a TableModel updates the JTable based on events, without the need to call repaint or the likes on the JTable).
However, when trying this in an SSCCE, I came to the following code (different versions, only post the most elaborate version)
without the scroll-pane, the validate calls seem to have no effect. I actually need to call pack again to make the new labels visible (not included in the SSCCE, but removing the scrollpane from the code is trivial)
with the scroll-pane, the validate call has an effect
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AddLabelsAtRuntime {
private int fLabelCounter = 0;
private JPanel fLabelPanel;
private final JFrame fTestFrame;
public AddLabelsAtRuntime() {
fLabelPanel = new JPanel( );
BoxLayout boxLayout = new BoxLayout( fLabelPanel, BoxLayout.PAGE_AXIS );
fLabelPanel.setLayout( boxLayout );
fTestFrame = new JFrame( "Dynamically add labels" );
}
private JFrame createUI(){
Container contentPane = fTestFrame.getContentPane();
contentPane.setLayout( new BorderLayout() );
JScrollPane scrollPane = new JScrollPane( fLabelPanel );
scrollPane.setPreferredSize( new Dimension( 200, 200 ) );
contentPane.add( scrollPane, BorderLayout.CENTER );
contentPane.add( createButtonPanel(), BorderLayout.SOUTH );
fTestFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
fTestFrame.pack();
return fTestFrame;
}
private void addLabel(){
fLabelPanel.add( new JLabel( "Label " + ++fLabelCounter ) );
}
private JPanel createButtonPanel(){
JPanel buttonPanel = new JPanel( );
BoxLayout boxLayout = new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS );
buttonPanel.setLayout( boxLayout );
JButton validateButton = new JButton( "Add + validate" );
validateButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
addLabel();
fLabelPanel.validate();
fTestFrame.validate();
}
} );
buttonPanel.add( validateButton );
JButton noValidateButton = new JButton( "Add" );
noValidateButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
addLabel();
}
} );
buttonPanel.add( noValidateButton );
JButton packButton = new JButton( "Add + pack" );
packButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
addLabel();
fTestFrame.pack();
}
} );
buttonPanel.add( packButton );
return buttonPanel;
}
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
#Override
public void run() {
AddLabelsAtRuntime addLabelsAtRuntime = new AddLabelsAtRuntime();
addLabelsAtRuntime.createUI().setVisible( true );
}
} );
}
}
Create Dynamic JButton with Image and ActionListener - Java Swing
Create JButton dynamically with Image and the ActionListener . You will be able to change the button height , width horizontal gap and vertical gap in one place.
you can find more details from here

How to make JTable both AutoResize and horizontall scrollable?

I am putting a JTable into a JScrollPane
But When I set JTable Auto Resizeable, then it won't have horizontal scroll bar.
if I set AUTO_RESIZE_OFF, then the Jtable won't fill the width of its container when the column width is not big enough.
So how can I do this:
when the table is not wide enough, expand to fill its container width
when the table is wide enough, make it scrollable.
Thanks
You need to customize the behaviour of the Scrollable interface.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableHorizontal extends JFrame
{
public TableHorizontal()
{
final JTable table = new JTable(10, 5)
{
public boolean getScrollableTracksViewportWidth()
{
return getPreferredSize().width < getParent().getWidth();
}
};
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
final JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
}
public static void main(String[] args)
{
TableHorizontal frame = new TableHorizontal();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setSize(400, 300);
frame.setVisible(true);
}
}
The above code basically sizes the component at its preferred size or the viewport size, whichever is greater.
If for some reason customising JTable is not an option (e.g. it might be created in third-party code), you can achieve the same result by setting it to toggle between two different JTable AUTO_RESIZE modes whenever the containing viewport is resized, e.g.:
jTable.getParent().addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(final ComponentEvent e) {
if (jTable.getPreferredSize().width < jTable.getParent().getWidth()) {
jTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
} else {
jTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
}
}
});
I found that all that is needed is to include
table = new JTable(model);
// this enables horizontal scroll bar
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
and then when the required viewport width and height have been calculated, include
frame.getContentPane().add(new JScrollPane(table))
table.setPreferredScrollableViewportSize(new Dimension(width,height));
If you set the Layout of its container to BorderLayout with a BorderLayout.CENTER layout constraint, then the JTable will auto resize to fit its container.
If you want to make a component scrollable, you can wrap the JTable with a JScrollPane.
setLayout(new BorderLayout());
add(new JScrollPane(new JTable()), BorderLayout.CENTER);

Categories