I failed to change the height of JPanel or JScrollPane to make more lines to appear, I used GridLayout. It seems that, every component in it should have the same size even when I use setSize(). Should I use another layout?
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Main {
private JFrame mainFrame;
private JLabel headerLabel;
private JLabel statusLabel;
private JPanel controlPanel;
private imagePanel image;
JTextField textField = new JTextField(20);
public Main() throws IOException{
prepareGUI();
}
class imagePanel extends JPanel {
private static final long serialVersionUID = 1L;
public void paint(Graphics g) {
try {
BufferedImage image = ImageIO.read(new File("file.jpg"));
g.drawImage(image, 170, 0, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException{
Main swingControlDemo = new Main();
swingControlDemo.showEventDemo();
}
private void prepareGUI(){
mainFrame = new JFrame("Java SWING Examples");
mainFrame.setSize(400,500);
GridLayout gridlayout = new GridLayout(4, 1);
gridlayout.setVgap(1);
mainFrame.setLayout(gridlayout);
headerLabel = new JLabel("",JLabel.CENTER );
statusLabel = new JLabel("",JLabel.CENTER);
JScrollPane scroller = new JScrollPane(statusLabel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
image = new imagePanel();
image.setLayout(new FlowLayout());
// mainFrame.add(headerLabel);
mainFrame.add(image);
mainFrame.add(controlPanel);
mainFrame.add(scroller);
mainFrame.setVisible(true);
}
private void showEventDemo(){
headerLabel.setText("Control in action: Button");
JButton okButton = new JButton("reload");
JButton submitButton = new JButton("Submit");
JButton cancelButton = new JButton("Cancel");
okButton.setActionCommand("reload");
submitButton.setActionCommand("Submit");
cancelButton.setActionCommand("Cancel");
okButton.addActionListener(new ButtonClickListener());
submitButton.addActionListener(new ButtonClickListener());
cancelButton.addActionListener(new ButtonClickListener());
controlPanel.add(okButton);
controlPanel.add(submitButton);
//controlPanel.add(cancelButton);
controlPanel.add(textField);
System.out.println("---------------------");
mainFrame.setVisible(true);
}
private class ButtonClickListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if( command.equals( "reload" )) {
statusLabel.setText(convertToMultiline("Line1\nLine2\nLine3\nLine4\nLine5\nLine6\nLine7\nLine8\nLine9\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine"));
}
else {
statusLabel.setText("Submit Button clicked.");
}
}
}
public static String convertToMultiline(String orig)
{
return "<html>" + orig.replaceAll("\n", "<br>");
}
}
The GUI need to look like this
I want to remove the large vertical gaps between the componets, and the jLabel should use that space
Well in your comment you say you want the label to use the space. But in your picture you show the text area with all the space. How can we answer a question when you give us conflicting requirements? Be specific and accurate when describing a problem.
In any case, the default layout of a JFrame is a BorderLayout so you would probably start with that.
Then the component that you want to grow/shrink as the frame is resized should be added to the CENTER of the frame.
Then you create a second panel to contain your other components. This panel would then be added to either the PAGE_START or PAGE_NORTH of the frame depending on your exact requirement.
The layout manager of this panel can then be whatever your want. Maybe a GridLayout, or a GridBagLayout or a vertical BoxLayout.
Read the section from the Swing tutorial on Layout Managers for more information and working examples. The key point is you create nest panels each with a different layout manager to achieve your layout.
Related
I am writing in a notepad. And I want to implement text scaling in my notepad. But I don't know how to do it. I'm trying to find it but everyone is suggesting to change the font size. But I need another solution.
I am create new project and add buttons and JTextArea.
package zoomtest;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JTextArea;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class zoom {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
zoom window = new zoom();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public zoom() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
JButton ZoomIn = new JButton("Zoom in");
ZoomIn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Code here...
}
});
panel.add(ZoomIn);
JButton Zoomout = new JButton("Zoom out");
Zoomout.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Code here...
}
});
panel.add(Zoomout);
JTextArea jta = new JTextArea();
frame.getContentPane().add(jta, BorderLayout.CENTER);
}
}
Introduction
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay close attention to the Laying Out Components Within a Container section.
I reworked your GUI. Here's how it looks when the application starts. I typed some text so you can see the font change.
Here's how it looks after we zoom out.
Here's how it looks after we zoom in.
Stack Overflow scales the images, so it's not as obvious that the text is zooming.
Explanation
Swing was designed to be used with layout managers. I created two JPanels, one for the JButtons and one for the JTextArea. I put the JTextArea in a JScrollPane so you could type more than 10 lines.
I keep track of the font size in an int field. This is a simple application model. Your Swing application should always have an application model made up of one or more plain Java getter/setter classes.
Code
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ZoomTextExample {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
new ZoomTextExample();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private int pointSize;
private Font textFont;
private JFrame frame;
private JTextArea jta;
private JTextField pointSizeField;
public ZoomTextExample() {
this.pointSize = 16;
this.textFont = new Font(Font.DIALOG, Font.PLAIN, pointSize);
initialize();
}
private void initialize() {
frame = new JFrame("Text Editor");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createButtonPanel(), BorderLayout.NORTH);
frame.add(createTextAreaPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
JButton zoomIn = new JButton("Zoom in");
zoomIn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
incrementPointSize(+2);
updatePanels();
}
});
panel.add(zoomIn);
panel.add(Box.createHorizontalStrut(20));
JLabel label = new JLabel("Current font size:");
panel.add(label);
pointSizeField = new JTextField(3);
pointSizeField.setEditable(false);
pointSizeField.setText(Integer.toString(pointSize));
panel.add(pointSizeField);
panel.add(Box.createHorizontalStrut(20));
JButton zoomOut = new JButton("Zoom out");
zoomOut.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
incrementPointSize(-2);
updatePanels();
}
});
panel.add(zoomOut);
return panel;
}
private JPanel createTextAreaPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
jta = new JTextArea(10, 40);
jta.setFont(textFont);
JScrollPane scrollPane = new JScrollPane(jta);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private void updatePanels() {
pointSizeField.setText(Integer.toString(pointSize));
textFont = textFont.deriveFont((float) pointSize);
jta.setFont(textFont);
frame.pack();
}
private void incrementPointSize(int increment) {
pointSize += increment;
}
}
I am a new java programmer and I use stackoverflow since my begin. I code a little "game", and it is a text-based game. Well, i begin a graphical interface, to case the text, and i would have this configuration
Basically, it is a double separation, with 3 horizontals elements. Actually, I have this:
and i want a separation
I have tried to put an other split pane on the top of the first one, like this:
package sample;
import javax.swing.*;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.*;
class Fenetresaisie extends JFrame {
public static class Fenetre {
public final static int HT = 1024;
public final static int LG = 758;
public static void main(String[] args) {
JPanel panel = new JPanel();
JFrame F = new JFrame("CORONAZE");
F.setExtendedState(JFrame.MAXIMIZED_BOTH);
F.setSize(HT, LG);
F.setVisible(true);
F.addWindowListener(new gestionFenetre());
ImageIcon icone = new ImageIcon("images.jpg");
JLabel image = new JLabel(icone);
JTextField textField = new JTextField();
textField.setFont(new Font("Terminal", Font.BOLD, 30));
textField.setForeground(Color.RED);
textField.setBackground(Color.black);
textField.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent e) {
textField.getText();
e.getKeyChar();
}
});
JLabel label = new JLabel(">texte de l'histoire ici<");
label.setOpaque(true);
label.setForeground(Color.green);
label.setBackground(Color.BLACK);
panel.add(label);
JSplitPane topJSplitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT, label, textField);
// topJSplitPane.setDividerLocation(400);
JSplitPane bottomJSplitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT, topJSplitPane, textField );
//i added it to have a double separation, but it give 2 sticked splitpane
F.add(topJSplitPane, BorderLayout.CENTER);
F.add(bottomJSplitPane, BorderLayout.SOUTH);
F.setVisible(true);
}
}
static class gestionFenetre extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
But it gives me two sticked splitpane :-/
Can you help me please? I hope you understand my message, because I learn English. Contact me below if you want a next phase to this issue, thanks! ^^ Here is the actual graphical test java class:
package sample;
import javax.swing.*;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.*;
class Fenetresaisie extends JFrame {
public static class Fenetre {
public final static int HT = 1024;
public final static int LG = 758;
public static void main(String[] args) {
JPanel panel = new JPanel();
JFrame F = new JFrame("CORONAZE");
F.setExtendedState(JFrame.MAXIMIZED_BOTH);
F.setSize(HT, LG);
F.setVisible(true);
F.addWindowListener(new gestionFenetre());
ImageIcon icone = new ImageIcon("images.jpg");
JLabel image = new JLabel(icone);
JTextField textField = new JTextField();
textField.setFont(new Font("Terminal", Font.BOLD, 30));
textField.setForeground(Color.RED);
textField.setBackground(Color.black);
textField.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent e) {
textField.getText();
e.getKeyChar();
}
});
JLabel label = new JLabel(">texte de l'histoire ici<");
label.setOpaque(true);
label.setForeground(Color.green);
label.setBackground(Color.BLACK);
panel.add(label);
JSplitPane topJSplitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT, label, textField);
topJSplitPane.setDividerLocation(400);
// JSplitPane bottomJSplitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT, topJSplitPane, textField );
//i added it to have a double separation, but it give 2 sticked splitpane
F.add(topJSplitPane, BorderLayout.CENTER);
// F.add(bottomJSplitPane, BorderLayout.SOUTH);
F.setVisible(true);
}
}
static class gestionFenetre extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
You wrote in your question
I am a new java programmer and I use stackoverflow since my begin
I really think that the way to learn Swing programming is to follow a learning curve that starts with the basics and gradually progresses. Everybody has his preferred way to learn, for example by attending a course or watching a video or reading a book. Personally I prefer books. If you do too, then I can recommend a few.
You also wrote in your question
I code a little "game"
I would say that is a very ambitious project for a beginner. While I'm sure that there are people who learn best by starting off with ambitious projects, I would say they are in the minority.
That said, the key to correctly implementing your GUI is having a deep understanding of how Swing works, in particular layout managers and Component sizes as well as at what point in the code can you set those Component sizes.
The below code will initially display your desired GUI, since I understand, from your question, that that is what you are trying to accomplish now.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class WindowCapture extends WindowAdapter implements Runnable {
private JFrame frame;
private JLabel label;
private JSplitPane splitPane;
private JSplitPane topPane;
#Override // java.lang.Runnable
public void run() {
showGui();
}
#Override // java.awt.event.WindowAdapter
public void windowOpened(WindowEvent event) {
int height = event.getWindow().getHeight();
splitPane.setDividerLocation(0.7);
double high = height * 0.7;
height = (int) Math.rint(high);
high = height * 0.8;
height = (int) Math.rint(high);
label.setPreferredSize(new Dimension(event.getWindow().getWidth(), height));
}
private JTextField createBottomPane() {
JTextField textField = new JTextField(20);
textField.setFont(new Font("Terminal", Font.BOLD, 30));
textField.setForeground(Color.RED);
textField.setBackground(Color.black);
return textField;
}
private JSplitPane createSplitPane() {
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createTopPane(), createBottomPane());
splitPane.setDividerLocation(0.4);
return splitPane;
}
private JSplitPane createTopPane() {
label = new JLabel(">texte de l'histoire ici<");
label.setOpaque(true);
label.setForeground(Color.green);
label.setBackground(Color.BLACK);
topPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
label,
new JPanel());
topPane.setDividerLocation(0.9);
return topPane;
}
public void showGui() {
frame = new JFrame("Window Capture");
frame.addWindowListener(this);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.add(createSplitPane());
frame.setVisible(true);
}
/**
* Start here!
*/
public static void main(String[] args) {
EventQueue.invokeLater(new WindowCapture());
}
}
Here is a screen capture of the running app.
I have a frame which contains a vertical toolbar with a combobox and some buttons. The combobox takes up the maximum height it can in the toolbar. Why? And how to solve this? Is there a way to fix the size of the combobox?
The code:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.border.BevelBorder;
public class Clipping extends JPanel {
public Clipping()
{
setLayout(new BorderLayout());
JToolBar toolbar = new JToolBar(JToolBar.VERTICAL);
CreateToolBarButtons(toolbar);
toolbar.setFloatable(false);
toolbar.setBorder(new BevelBorder(BevelBorder.RAISED));
add(toolbar, BorderLayout.WEST);
}
private static void CreateToolBarButtons(JToolBar toolbar)
{
String[] cboList = {"Line", "Polygon"};
JComboBox cboDraw = new JComboBox(cboList);
JButton btnClip = new JButton("Set clip area");
JButton btnClear = new JButton("Clear");
toolbar.add(cboDraw);
toolbar.addSeparator();
toolbar.add(btnClip);
toolbar.addSeparator();
toolbar.add(btnClear);
}
public static void main(String[] args)
{
CreateFrame();
}
private static void CreateFrame()
{
JFrame frame = new JFrame("Clipping");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Clipping());
frame.setSize(500,500);
frame.setVisible(true);
}
}
JToolbar uses a BoxLayout and JComboBox has an issue with it. See this question for a solution. Rather than creating a subclass, try to just setMaximumSize on the combo box with the height that you like.
I am trying to create a Java GUI application that contains a label and button. When the button is clicked the background color of the first panel is changed. I've got the label and button but getting errors whenever I click the button. Also, I wanted the first panel to originally have a yellow background then switch to whatever color. Here's my code:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
public class ChangeDemo extends JFrame implements ActionListener
{
public static final int WIDTH = 300;
public static final int HEIGHT= 200;
private JPanel biggerPanel;
public static void main(String[] args)
{
ChangeDemo gui = new ChangeDemo();
gui.setVisible(true);
}
public ChangeDemo()
{
super ("ChangeBackgroundDemo");
setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(2,3));
JPanel biggerPanel = new JPanel();
biggerPanel.setLayout(new BorderLayout());
biggerPanel.setBackground(Color.YELLOW);
JLabel namePanel = new JLabel("Click the button to change the background color");
biggerPanel.add(namePanel, BorderLayout.NORTH);
add(namePanel);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.setBackground(Color.LIGHT_GRAY);
JButton changeButton = new JButton("Change Color");
changeButton.addActionListener(this);
buttonPanel.add(changeButton);
add(buttonPanel);
}
public void actionPerformed(ActionEvent e)
{
String buttonString = e.getActionCommand();
if(buttonString.equals("Change Color"))
biggerPanel.setBackground(Color.RED);
else
System.out.println("Unexpected Error!");
}
}
I made a few changes to your code.
First, you must start a Swing application with a call to SwingUtilities.invokeLater.
public static void main(String[] args) {
SwingUtilities.invokeLater(new ChangeDemo());
}
Second, you use Swing components. You only extend a Swing component when you want to override a method of the Swing component.
Third, I made a action listener specifically for your JButton. That way, you don't have to check for a particular JButton string. You can create as many action listeners as you need for your GUI.
JButton changeButton = new JButton("Change Color");
changeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
isYellow = !isYellow;
if (isYellow) buttonPanel.setBackground(Color.YELLOW);
else buttonPanel.setBackground(Color.RED);
}
});
Finally, I changed the background color of the JButton panel.
Here's the entire ChangeDemo class.
package com.ggl.testing;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ChangeDemo implements Runnable {
private boolean isYellow;
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new ChangeDemo());
}
#Override
public void run() {
frame = new JFrame("Change Background Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
JPanel namePanel = new JPanel();
JLabel nameLabel = new JLabel(
"Click the button to change the background color");
nameLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
namePanel.add(nameLabel);
mainPanel.add(namePanel);
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.setBackground(Color.YELLOW);
isYellow = true;
JButton changeButton = new JButton("Change Color");
changeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
isYellow = !isYellow;
if (isYellow) buttonPanel.setBackground(Color.YELLOW);
else buttonPanel.setBackground(Color.RED);
}
});
buttonPanel.add(changeButton);
mainPanel.add(buttonPanel);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
Here is working demo based on amendments to your code, haven't had time to tidy it up but hopefully you'll get the gist of it. Problem was you hand't added Panels to the borders (north, south etc.) in order to color them. Hopefully this helps.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
public class ChangeDemo extends JFrame implements ActionListener
{
public static final int WIDTH = 300;
public static final int HEIGHT= 200;
private JPanel biggerPanel = new JPanel();
private JPanel namePanel = new JPanel();
public static void main(String[] args)
{
ChangeDemo gui = new ChangeDemo();
gui.setVisible(true);
}
public ChangeDemo()
{
super ("ChangeBackgroundDemo");
setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(2,3));
//JPanel biggerPanel = new JPanel();
this.biggerPanel.setLayout(new BorderLayout());
this.biggerPanel.setBackground(Color.YELLOW);
JLabel nameLabel = new JLabel("Click the button to change the background color");
namePanel.add(nameLabel);
namePanel.setBackground(Color.YELLOW);
//this.biggerPanel.add(namePanel, BorderLayout.NORTH);
add(namePanel);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.setBackground(Color.LIGHT_GRAY);
JButton changeButton = new JButton("Change Color");
changeButton.addActionListener(this);
changeButton.setActionCommand("Change Color");
buttonPanel.add(changeButton);
add(buttonPanel);
}
public void actionPerformed(ActionEvent e)
{
String buttonString = e.getActionCommand();
if(buttonString.equals("Change Color"))
this.namePanel.setBackground(Color.RED);
else
System.out.println("Unexpected Error!");
}
}
I'm trying to add 2 images inside the JScrollPane. the first image is a background and the second one overlap the first one. The problem shows only the second image when i run my program!
please help
ImageIcon ii = new ImageIcon("mini_map.png");
JLabel label1=new JLabel(ii);
Icon icon = new ImageIcon("Mg.gif");
JLabel label2 = new JLabel(icon);
JScrollPane jsp=new JScrollPane();
jsp.getViewport().add(label1);
jsp.getViewport().add(label2 );
JViewport is a single-child container, you can't add two components.
To achieve an overlap (that is stack components in z-direction) in any container, you'r mostly on your own, the built-in support is poor. Either have to manage them in LayeredPane (as mentioned already) or try OverlapLayout
Put both labels in the same panel and add it to the JScrollPane:
ImageIcon ii = new ImageIcon("mini_map.png");
JLabel label1=new JLabel(ii);
Icon icon = new ImageIcon("Mg.gif");
JLabel label2 = new JLabel(icon);
JPanel pContainer = new JPanel();
pContainer.add(label1);
pContainer.add(label2);
JScrollPane jsp=new JScrollPane(pContainer);
If you want to have components on top of each other use a layered pane.
This is how I would do it for your particular problem.
Since you say you have one image which serves the role of a background, thus I would override paintComponent() like in BackgroundPanel below.
This way you have a panel which serves as a background only. To it you can add any type of component, in your case a JLabel with an ImageIcon.
This way you have an effect of one being over another and you are still able to use layout manager to control where your components are.
If your problem is more complex or you want to generally set Components one over another then do as all are saying here ---> use JLayeredPane. Note that if you use JLayeredPane sadly layout managers will not help you since it doesn't respects them. You will have to proceed similarly to a situation when you use a null manager, i.e. setBounds() for components.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class PaintInScroll
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
try
{
Image backgroundImage = new ImageIcon(new URL(
"http://www.jvsearch.com/adidocs7_images/JAVAORANGE.JPG")).getImage();
BackgroundPanel bP = new BackgroundPanel(backgroundImage);
bP.setLayout(new BorderLayout());
bP.setPreferredSize(new Dimension(500, 500));
JLabel label = new JLabel(new ImageIcon(new URL(
"https://blogs.oracle.com/theplanetarium/resource/thumb-java-duke-guitar.png")));
bP.add(label, BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane(bP);
scrollPane.setPreferredSize(new Dimension(300, 400));
JPanel contentPane = new JPanel();
contentPane.add(scrollPane);
JFrame f = new JFrame();
f.setContentPane(contentPane);
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}catch(MalformedURLException ex)
{
Logger.getLogger(PaintInScroll.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}
class BackgroundPanel extends JPanel
{
private Image image;
public BackgroundPanel(Image image)
{
this.image = image;
}
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
}
}
NOTE: Images are URLs thus i-net connection is required to run the example.
EDIT1: Example showing how to use JLayeredPane with use of layout managers for each layer.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class PaintInScrollRespectingLayoutManagers extends JPanel
{
private static final long serialVersionUID = 1L;
private JLayeredPane layeredPane;
private JLabel imageContainer = new JLabel();
private JButton infoB = new JButton("i");
private JScrollPane scrollPane;
public PaintInScrollRespectingLayoutManagers(ImageIcon image)
{
super();
this.imageContainer.setIcon(image);
scrollPane = new JScrollPane(imageContainer);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(125, 90));
JPanel iSPP = new JPanel();//image scroll pane panel
iSPP.setOpaque(false);
iSPP.add(scrollPane);
JPanel iBP = new JPanel();//info button panel
iBP.setOpaque(false);
iBP.add(infoB);
this.layeredPane = new JLayeredPane();
layeredPane.add(iSPP, new Integer(50));
layeredPane.add(iBP, new Integer(100));
this.setLayout(new BorderLayout());
this.add(layeredPane, BorderLayout.CENTER);
this.add(new JButton("A button"), BorderLayout.SOUTH);
layeredPane.addComponentListener(layeredPaneCL);
setPreferredSize(new Dimension(300, 300));
}
private ComponentListener layeredPaneCL = new ComponentAdapter()
{
#Override
public void componentResized(ComponentEvent e)
{
super.componentResized(e);
System.out.println("componentResized");
for(Component c : layeredPane.getComponents())
c.setSize(layeredPane.getSize());
}
};
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
try
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PaintInScrollRespectingLayoutManagers(new ImageIcon(new URL(
"http://www.prodeveloper.org/wp-content/uploads/2008/10/stackoverflow-logo-250.png"))));
frame.pack();
frame.setVisible(true);
}catch(MalformedURLException ex)
{
Logger.getLogger(PaintInScrollRespectingLayoutManagers.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}
NOTE 2: The only reason that the scroll panes have setPrefferedSize is so you can see the scrollbars. Otherwise do not use it let the layout take care of controlling scroll pane.