This seems like a newbie question except that I've been trying to wrap my head around the Swing framework for loong time.
Provided you provide an image, dog.jpg, at least 500 px square, the following code should display the image in a scrollpane. If it displayed anything, I probably wouldn't throw my hands up in despair. What am I missing?
import java.awt.BorderLayout;
import javax.swing.*;
public class ScrollSample {
public static void main(String args[]) {
String title = (args.length == 0 ? "JScrollPane Sample" : args[0]);
new ScrollSample( title ) ;
}
public ScrollSample ( String title) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Icon icon = new ImageIcon("dog.jpg");
JLabel dogLabel = new JLabel(icon);
dogLabel.setSize( 500, 500 ) ;
JLayeredPane layeredPane = new JLayeredPane() ;
layeredPane.add( dogLabel, new Integer( 0 )) ;
JPanel jp = new JPanel() ;
jp.add( layeredPane ) ;
jp.setSize( 500, 500 ) ;
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(jp);
frame.getContentPane().add( scrollPane, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Thanks!
You must set the preferred size for JLayeredPane if you are drawing components of larger widths and sizes to it. Especially since you are adding it to a JPanel with default layout. JLayeredPanes don't have layout managers by default - so either you manage the bounds or add a preferred layout manager to the layered pane. The simple way would be:
After
JLayeredPane layeredPane = new JLayeredPane() ;
add
layeredPane.setPreferredSize(new Dimension(500,500));
And then maximize your window ( or set your JFrame's size to 600X600) when the app runs.
Read up on : How to Use Layered Panes
The default layout of a JPanel is a Flowlayout. A FlowLayout shows
each component at its preferred size and has a 5 pixel border. Use a
BorderLayout instead (or add the layered pane directly to the scroll pane).
The default preferred size of a JLayeredPane is (0, 0). Set a
preferred size for it.
A Swing GUI should be started on the EDT. Left as an exercise for the user.
import java.awt.*;
import javax.swing.*;
import java.net.URL;
public class ScrollSample {
public static void main(String args[]) throws Exception {
final URL url = new URL("http://pscode.org/media/stromlo2.jpg");
String title = (args.length == 0 ? "JScrollPane Sample" : args[0]);
new ScrollSample( title, url ) ;
}
public ScrollSample ( String title, URL url) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Icon icon = new ImageIcon(url);
JLabel dogLabel = new JLabel(icon);
dogLabel.setBounds(0,0,640,480);
JLayeredPane layeredPane = new JLayeredPane() ;
layeredPane.add( dogLabel, new Integer( 0 )) ;
layeredPane.setPreferredSize( new Dimension(500, 500) ) ;
JPanel jp = new JPanel(new BorderLayout()) ;
jp.add( layeredPane ) ;
JScrollPane scrollPane = new JScrollPane(jp);
frame.getContentPane().add( scrollPane, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Related
Im trying to make a option menu to be able to choose flags to be displayed, Im trying to put the tailand button on the left down corner and it seems it does not want to budge.
import java.awt.*;
import javax.swing.*;
public class Flags {
public static void startup() {
Dimension d = new Dimension(400,300);
JFrame menu = new JFrame("Flag Menu");
menu.setResizable(true);
JButton tailand = new JButton("Tailand");
JPanel tailandPanel = new JPanel();
tailand.setLayout(null);
tailandPanel.setLayout(null);
tailand.setBounds(300,100,100,600);
tailandPanel.add(tailand);
menu.add(tailandPanel);
tailandPanel.setBackground(Color.LIGHT_GRAY);
tailand.setBackground(Color.WHITE);
tailandPanel.setPreferredSize(d);
tailand.setPreferredSize(d);
tailandPanel.setLocation(1, 1);
tailand.setLocation(1, 1);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menu.setLocationRelativeTo(null);
menu.setSize(600, 400);
menu.setResizable(false);
menu.setVisible(true);
menu.setLocationRelativeTo(null);
}
}
I have tried tailand.setPreferredSize(d); and tailandpanel.setPreferredSize(d); but no luck.
Also Is their a way to use center mode? (Eg. Give 300,200 and the center of the button would be their?)
Don't use null layouts
Don't use setPreferredSize(...)
Swing was designed to be used with layout managers
For example:
JButton button = new JButton( "Tailand" );
JPanel left = new JPanel( new BorderLayout() );
left.setBackground( Color.WHITE );
left.add(button, BorderLayout.PAGE_END);
JFrame frame = new JFrame("Flag Menu");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frane.setLocationRelativeTo(null);
frame.add(left, BorderLayout.LINE_START);
frame.setSize(600, 400);
frame.setVisible(true);
Read the section from the Swing tutorial on Layout Manager for more information and example of using each layout manager.
I am creating a game which has a background image with cards displayed overtop. I would like to place the background image and cards such that they're always centered vertically and horizontally, even upon resizing the JFrame.
Currently, I am creating the cards (each a JPanel) and adding them into a container JPanel (no layout manager), then I add that Jpanel to the JFrame. After that I place the background image in a JPanel, then add that JPanel to the JFrame. The result is: The background image is hidden behind the cards and revealed when removing each card as desired. The background image is always centered but the card's JPanel does not move around upon resize. I am having a hard time getting the cards to always be centered, no matter what I try. I also need to add another JPanel to the JFrame in the South border, so that will need to work as well. I appreciate your assistance!
In the class that extends JFrame:
setSize(1060,700);
cardPanel = new JPanel();
cardPanel.setSize(1060,700);
cardPanel.setOpaque(false);
cardPanel.setLayout(null);
...card.setLocation(x, y); //loop through cards
...cardPanel.add(card); //and add each one
add(cardPanel, BorderLayout.CENTER); //add cardPanel to JFrame
//Add background image
bgPanel = new JPanel();
URL url = getClass().getResource("images/dragon_bg.png");
imgIcon = new ImageIcon(url);
JLabel background = new JLabel(imgIcon);
bgPanel.setLayout(new BorderLayout());
bgPanel.add(background);
add(bgPanel, BorderLayout.CENTER);
setVisible(true);
I would like to place the background image and cards such that they're always centered vertically and horizontally, even upon resizing the JFrame.
Then you need to use layout managers on your panels. The layout manager is responsible for redoing the layout.
How to add two JPanels to a JFrame in the center?
You could try using the OverlayLayout for this. I think the basic code would be:
JPanel contentPane = new JPanel( new GrigBagLayo9ut() );
frame.add(contentPane, BorderLayout.CENTER);
JPanel overlay = new JPanel()
overlay.setLayout( new OverlayLayout(overlay) );
contentPane.add(overlay, new GridBagConstraints()); // this should center the overlay panel
overlay.add(yourCardPanel); // you care panel must use a suitable layout
overlay.add(new JLabel() ); // use a JLabel for the background not a custom panel
I also need to add another JPanel to the JFrame in the South border,
The default layout manager for a JFrame's content pane is a BorderLayout. We already added the game panel to the center, so know you just add your other panel to the SOUTH.
If the OverlayLayout doesn't work the way you want then you will need to nest panels. Something like:
JPanel center = new JPanel( new GridBagLayout() );
frame.add(center, BorderLayout.CENTER);
JLabel background = new JLabel(...);
background.setLayoutManager( new GridBagLayout() );
center.add(background, new GridBagConstraints());
background.add(yourCardPanel, new GridBagConstraints());
Edit:
Using nested panels:
import java.awt.*;
import javax.swing.*;
public class GridBagLayoutCenter extends JPanel
{
public GridBagLayoutCenter()
{
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon("mong.jpg") );
background.setLayout( new GridBagLayout() );
add(background, BorderLayout.CENTER);
JPanel tiles = new JPanel();
tiles.setPreferredSize( new Dimension(200, 200) );
tiles.setBackground( Color.RED );
background.add(tiles, new GridBagConstraints());
add(new JLabel("SOUTH"), BorderLayout.SOUTH);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("GridBagLayoutCenter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new GridBagLayoutCenter() );
frame.setSize(400, 400);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
The preferred size of the "tiles" panel should not be hardcoded. The size should be determined by your custom layout manager based on the tiles that you add to the panel. The size should not change as tiles are removed.
I ultimately decided to place the background image in the card panel itself, then put the card panel in a box layout manager so that it's always centered. I renamed cardPanel to gameBoard. Definitely could be cleaner, but I can only work with my requirements.
setSize(new Dimension(1000, 600));
gameBoard = new JPanel();
gameBoard.setLayout(null);
gameBoard.setOpaque(false);
Dimension expectedDimension = new Dimension(920, 500);
gameBoard.setPreferredSize(expectedDimension);
gameBoard.setMaximumSize(expectedDimension);
gameBoard.setMinimumSize(expectedDimension);
//add cards to gameBoard here
JLabel background = new JLabel( new ImageIcon( getClass().getResource("images/graphic.png") ) );
background.setLocation(79,0); //manually center graphic
background.setBounds(new Rectangle(0, 0, 920, 500));
gameBoard.add(background);
Box centerBox = new Box(BoxLayout.Y_AXIS);
centerBox.setOpaque(true);
centerBox.setBackground(Color.WHATEVER);
centerBox.add(Box.createVerticalGlue());
centerBox.add(gameBoard);
centerBox.add(Box.createVerticalGlue());
add(centerBox);
setVisible(true);
I have a main Panel and I'm adding components dynamically into that one.
Main Panel has GridLayout limited to 3 columns and 0 rows (0 rows will allow rows to grow infinitely), but the problem is that I want all components to have fixed size or component's preferred size.
I can use other layout if it meets my requirements... but for now only GridLayout allows me to limit columns to 3...
I forgot to mention, Main Panel is added into JScrollpane, so I can scroll vertically.
One way to to do this is to use JPanels. GridLayout will stretch your components, but if you wrap the component in a JPanel, then the JPanel gets stretched. And since JPanel uses FlowLayout, which does not stretch components, your components remain at their preferred size.
Here's an example using JButton. Notice how I add them to a (new) JPanel each loop, then I add the panel to the grid layout.
import javax.swing.*;
public class GridLayout {
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setLayout( new java.awt.GridLayout( 0, 3 ) );
for( int i = 0; i < 21; i++ ) {
JPanel panel = new JPanel(); // Make a new panel
JButton button = new JButton( "Button "+i );
panel.add( button ); // add the button to the panel...
frame.add( panel ); // ...then add the panel to the layout
}
frame.pack();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
} );
}
}
I am trying to add a JLayeredPane to a JPanel and then add an image (JLabel icon) and a button to the JLayeredPane, but neither show up. I've tested the image without the button and the layeredpane so I know that works. Here is some of the code I am using. Is there something I am missing or doing wrong?
public class MyClass extends JPanel
{
private JLayeredPane layeredPane;
private JLabel imageContainer = new JLabel();
private JButton info = new JButton("i");
MyClass(ImageIcon image)
{
super();
this.imageContainer.setIcon(image);
this.layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(300, 300));
layeredPane.add(imageContainer, new Integer(50));
layeredPane.add(info, new Integer(100));
this.add(layeredPane);
}
}
From the tutorial
By default a layered pane has no layout manager. This means that you typically have to write the code that positions and sizes the components you put in a layered pane.
See the changes to your code:
import java.awt.*;
import javax.swing.*;
public class MyClass extends JPanel {
private JLayeredPane layeredPane;
private JLabel imageContainer = new JLabel();
private JButton info = new JButton("i");
MyClass(ImageIcon image) {
super();
this.imageContainer.setIcon(image);
this.layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(300, 300));
layeredPane.add(imageContainer, new Integer(50));
layeredPane.add(info, new Integer(100));
this.add(layeredPane);
// CHANGED CODE
// Manually set layout the components.
imageContainer.setBounds( 0, 0,
image.getIconWidth(),
image.getIconHeight() );
info.setBounds( 200, 00, 50, 40 );
}
public static void main( String [] args ) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new MyClass( new ImageIcon("logo.png") ) );
frame.pack();
frame.setVisible( true );
}
}
Additional notes:
1) It is better ( in my opinion ) to put the opening brace in the same line. That's how most Java code looks like.
2) Avoid inheriting from JPanel ( or any other component ) if you don't are not really creating a subclass. You can use it directly without having to inherit ( unless you're indeed creating a new component.
JLayeredPane has a null layout manager by default, so in your example you'll need to set the location and size of the child components. You can set a layout manager on the JLayeredPane, but that will most likely negate the layered rendering I'm guessing you want, since you're using a layered pane.
I have created a JFrame, and now I want to add a JLabel and textfields in it. Please tell me how to do that. I have used the following code but its not working.
JFrame i_frame = new JFrame("Select Locations");
i_from = new JLabel("From");
i_frame.getContentPane().add(i_from);
i_frame.add(Box.createRigidArea(new Dimension(2,0)));
i_frame.setLocationRelativeTo(null);
i_frame.setSize(200,200);
i_frame.setVisible(true);
Problem is this code is showing frame window but it is not showing label in it. Please help.
That's your first question, later you'll ask:
How do I get the value from my text field
So, I suggest you to take a look at this tutorial
http://java.sun.com/docs/books/tutorial/uiswing/start/index.html
And ask us if you have questions from that tutorial. Using an IDE will simplify your life.
Here's a start anyway:
Code:
import javax.swing.*;
import java.awt.Color;
public class MyApp {
public static void main( String [] args ) {
JFrame frame = new JFrame();
frame.setBackground( new Color(0,0,0,64 ));
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JPanel top = new JPanel();
top.add( new JLabel("What is your name"){{
setForeground(Color.white);
}});
top.add( new JTextField(10) );
frame.add( top );
frame.pack();
frame.setVisible( true );
}
}
EDIT
Dismiss this answer. It was posted when the question was rather ambiguous. I'm leaving it as CW for it may be helpful.
plus OSX frames with alpha background are too cool!
The main issue is the layout being used by the content pane (most likely JRootPane.RootLayout, A custom layout manager that is responsible for the layout of layeredPane, glassPane, and menuBar ) is not the best. This code should work;
JFrame i_frame = new JFrame("Select Locations");
JLabel i_from = new JLabel("From");
i_frame.getContentPane().setLayout(new FlowLayout());
i_frame.getContentPane().add(i_from);
i_frame.add(Box.createRigidArea(new Dimension(2,0)));
i_frame.setLocationRelativeTo(null);
i_frame.setSize(200,200);
i_frame.setVisible(true);
setting a different layout does the trick
The problem is that you are adding a second component (Box.createRigidArea) in the same layout position (BorderLayout.CENTER) as the Label.
JFrame.add() results in the same as JFrame.getContentPane().add()...
So the label is being replaced by the RigidArea.
Try this:
JFrame i_frame = new JFrame("Select Locations");
i_from = new JLabel("From");
i_frame.getContentPane().add(i_from);
// i_frame.add(Box.createRigidArea(new Dimension(2,0)));
i_frame.setLocationRelativeTo(null);
i_frame.setSize(200,200);
i_frame.setVisible(true);
to add more components, change the LayoutManager:
JFrame i_frame = new JFrame("Select Locations");
JLabel i_from = new JLabel("From");
Container pane = i_frame.getContentPane();
pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS)); // any LayoutManager you need
pane.add(i_from);
pane.add(Box.createRigidArea(new Dimension(2,0))); // space after JLabel ?
i_frame.setSize(200,200); // better done before setLocationRelativeTo
i_frame.setLocationRelativeTo(null);
i_frame.setVisible(true);
Note: if you "just" want to add an empty border to your label, use a setBorder() instead of the RigidArea:
i_from.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
[]]
For adding JLabel to JFrame see the line of code see here
public class JLabelExample extends JFrame {
JLabel jLabel;
public JLabelExample() {
jLabel = new JLabel();
jLabel.setText("tutorialData.com");
jLabel.setForeground(Color.BLUE);
this.add(jLabel);
}
public static void main(String a[]) {
JLabelExample labelExample = new JLabelExample();
labelExample.setSize(250, 200);
labelExample.setTitle("tutorialData.com");
labelExample.setVisible(true);
}
}
Please refer more on JFrame