Does Adding a Jlabel to a JPAnel "Hide" the JPAnel

Adding/removing jlabels from jpanel

You can use Drag-and-Drop for this, or you can use a Mouselistener and MouseMotionListener. One example of the latter can be seen in my code here:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Chess2 {
private static void createAndShowUI() {
JFrame frame = new JFrame("Chess 2");
frame.getContentPane().add(new Chess2Gui().getMainComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}

class Chess2Gui {
private static final int RANKS = 8;
private static final int FILES = 8;
private static final Color DARK_COLOR = new Color(0, 100, 0);
private static final Color LIGHT_COLOR = new Color(200, 200, 200);
private static final Color DARK_PIECE_COLOR = Color.black;
private static final int SQR_WIDTH = 80;
private static final int PIECE_WIDTH = 60;
private static final Dimension SQR_SIZE = new Dimension(SQR_WIDTH, SQR_WIDTH);

private JLayeredPane mainLayeredPane = new JLayeredPane();
private JPanel board = new JPanel(new GridLayout(RANKS, FILES));
private JPanelSquare[][] jPanelSquareGrid = new JPanelSquare[RANKS][FILES];

public Chess2Gui() {
for (int rank = 0; rank < RANKS; rank++) {
for (int file = 0; file < FILES; file++) {
Color bkgd = DARK_COLOR;
if (rank % 2 == file % 2) {
bkgd = LIGHT_COLOR;
}
jPanelSquareGrid[rank][file] = new JPanelSquare(rank, file, bkgd);
jPanelSquareGrid[rank][file].setPreferredSize(SQR_SIZE);
board.add(jPanelSquareGrid[rank][file]);
}
}
board.setSize(board.getPreferredSize());
board.setLocation(0, 0);
mainLayeredPane.add(board, JLayeredPane.DEFAULT_LAYER);
mainLayeredPane.setPreferredSize(board.getPreferredSize());

ImageIcon icon = new ImageIcon(ImageUtils2.createImage(PIECE_WIDTH, DARK_PIECE_COLOR));
JLabel chessPiece = new JLabel(icon, SwingConstants.CENTER);

jPanelSquareGrid[1][3].add(chessPiece);

MyMouseAdapter mouseAdapter = new MyMouseAdapter();
mainLayeredPane.addMouseListener(mouseAdapter);
mainLayeredPane.addMouseMotionListener(mouseAdapter);

}

public JComponent getMainComponent() {
return mainLayeredPane;
}

private class MyMouseAdapter extends MouseAdapter {
private JLabel piece = null;
private Point delta = null;
private int oldRank = -1;
private int oldFile = -1;

@Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = board.getComponentAt(p);
for (int rank = 0; rank < jPanelSquareGrid.length; rank++) {
for (int file = 0; file < jPanelSquareGrid[rank].length; file++) {
if (jPanelSquareGrid[rank][file] == c) {
if (jPanelSquareGrid[rank][file].getChessPiece() != null) {

// the jPanelSquares are derived from JPanel but have a
// few of their own methods
piece = jPanelSquareGrid[rank][file].getChessPiece();
jPanelSquareGrid[rank][file].remove(piece);
oldRank = rank;
oldFile = file;
mainLayeredPane.add(piece, JLayeredPane.DRAG_LAYER);
int x = p.x - PIECE_WIDTH / 2;
int y = p.y - PIECE_WIDTH / 2;
piece.setLocation(x, y);

delta = new Point(p.x - x, p.y - y);
board.revalidate();
mainLayeredPane.repaint();
return;
}
}
}
}

oldFile = -1;
oldRank = -1;
}

@Override
public void mouseDragged(MouseEvent e) {
if (piece != null) {
Point p = e.getPoint();
int x = p.x - delta.x;
int y = p.y - delta.y;
piece.setLocation(x, y);
mainLayeredPane.revalidate();
mainLayeredPane.repaint();
}
}

@Override
public void mouseReleased(MouseEvent e) {
if (piece != null) {
JPanelSquare sqr = (JPanelSquare) board.getComponentAt(e.getPoint());
mainLayeredPane.remove(piece);
if (sqr == null || !validMove(sqr)) {
jPanelSquareGrid[oldRank][oldFile].add(piece);
} else {
sqr.add(piece);
}

piece = null;
delta = null;

oldRank = -1;
oldFile = -1;

board.revalidate();
mainLayeredPane.repaint();
}
}

// just a pawn's moves
private boolean validMove(JPanelSquare sqr) {
int rank = sqr.getRank();
int file = sqr.getFile();

if (file != oldFile) {
return false;
}
if (oldRank == 1 && (rank != 2 && rank != 3)) {
return false;
}
if (oldRank != 1 && rank != oldRank + 1) {
return false;
}
return true;
}
}
}

@SuppressWarnings("serial")
class JPanelSquare extends JPanel {
private int rank;
private int file;
private JLabel chessPiece = null;

public JPanelSquare(int rank, int file, Color bkgrnd) {
this.rank = rank;
this.file = file;
setBackground(bkgrnd);
setLayout(new GridBagLayout());
}

public int getRank() {
return rank;
}

public int getFile() {
return file;
}

@Override
public Component add(Component c) {
chessPiece = (JLabel) c;
return super.add(c);
}

@Override
public void remove(Component comp) {
chessPiece = null;
super.remove(comp);
}

public JLabel getChessPiece() {
return chessPiece;
}
}

class ImageUtils2 {

public static BufferedImage createImage(int size, Color color) {
BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(color);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.fillOval(size / 3, 0, size / 3, size / 3);
g2.fillOval(size / 4, size / 4, size / 2, 2 * size / 3);
g2.fillOval(size / 6, 2 * size / 3, 2 * size / 3, size / 2);
g2.dispose();
return img;
}

}

This uses a JLayeredPane and when the user selects a piece, it (a JLabel) gets removed from
board JPanel and raised to the JLayeredPane's DRAG_LAYER, until it is released over a valid position.

Note, this code was taken from my previous answer here. For more details on the code, please check out that answer.

How to make my user-interface self adapt to the show and hide of JPanel?

I rewrote your code. Explanations appear after it.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;

public class Demo2 implements ActionListener, Runnable {
private static final String HIDE = "HIDE";
private static final String SHOW = "SHOW";

private JButton button;
private JLabel lbl2;
private JFrame frame;
private JTextField txf2;

@Override
public void run() {
showGui();
}

@Override
public void actionPerformed(ActionEvent event) {
boolean visible;
String text;
String actionCommand = event.getActionCommand();
switch (actionCommand) {
case HIDE:
text = SHOW;
visible = false;
break;
case SHOW:
text = HIDE;
visible = true;
break;
default:
text = "???";
visible = false;
}
button.setText(text);
lbl2.setVisible(visible);
txf2.setVisible(visible);
}

private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
button = new JButton(SHOW);
button.addActionListener(this);
buttonsPanel.add(button);
return buttonsPanel;
}

private JScrollPane createForm() {
JPanel form = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;

JLabel lbl1 = new JLabel("lbl1");
form.add(lbl1, gbc);

gbc.gridx = 1;
JTextField txf1 = new JTextField(6);
form.add(txf1, gbc);

gbc.gridx = 0;
gbc.gridy = 1;

lbl2 = new JLabel("lbl2");
lbl2.setVisible(false);
form.add(lbl2, gbc);

gbc.gridx = 1;
txf2 = new JTextField(6);
txf2.setVisible(false);
form.add(txf2, gbc);

gbc.gridx = 0;
gbc.gridy = 2;

JLabel lbl3 = new JLabel("lbl3");
form.add(lbl3, gbc);

gbc.gridx = 1;
JTextField txf3 = new JTextField(6);
form.add(txf3, gbc);

return new JScrollPane(form,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}

private void showGui() {
frame = new JFrame("Demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(createForm(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

/**
* Start here.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Demo2());
}
}

You should always try to use a layout manager. The code above uses GridBagLayout but there are several other layout managers that are good at handling forms, including GroupLayout and SpringLayout as well as third party layout managers like MiG Layout and FormLayout.

In order to "show" and "hide" the middle row in your form, simply set the visible property to true or false. If the text of the button is SHOW, then when the user clicks on it, I change the button text to HIDE and make lbl2 and txf2 both visible. If the button text is HIDE, then when the user clicks the button I change the text to SHOW and make lbl2 and txf2 not visible.

Because I use a layout manager, it handles resizing the JPanel whenever the contents of the JPanel are changed. When you don't use a layout manager, then you have to write code that handles the resizing and of-course your code does not, hence your problem.

When to use JFrame, JLabel, and JPanel

For the most part, JPanel is a container that allows for better organization. When you need to organize your components of your gui, you should use a JPanel and define a layout for the JPanel. You can also nest JPanels within each other and etc. JLabels don't have the capability of defining layouts for further components to be displayed inside the JLabel.

How to show/hide JPanel on top of another JPanel in a JFrame?

Thanks to brainiac I came up with this as a solution, and it's working as expected:

public void toggleSettings(){
if(this.jLabelEmargement.isVisible()){
// Set size of JPanel
FSettings.setSize(222, 380);
// Set location of JPanel
FSettings.setLocation(0, 150);
// Show JPanel
FSettings.setVisible(true);
FSettings.setBackground(new Color(226,236,241));
// Add JPanel to LayeredPane
jLayeredPaneSettings.add(FSettings, new Integer(5));
this.frameLearners.setVisible(false);
this.jLabelEmargement.setVisible(false);
this.jLabelFinalEval.setVisible(false);
this.jLabelLeaners.setVisible(false);
ImageIcon icon = new ImageIcon(getClass().getResource("/com/images/cog_00997d_28.png"));
jLabelSettings.setIcon(icon);
}
else{
// Hide JPanel
FSettings.setVisible(false);
// Remove from LayeredPane
jLayeredPaneSettings.remove(FSettings);
this.frameLearners.setVisible(true);
this.jLabelEmargement.setVisible(true);
this.jLabelFinalEval.setVisible(true);
this.jLabelLeaners.setVisible(true);
ImageIcon icon = new ImageIcon(getClass().getResource("/com/images/cog_000000_28.png"));
jLabelSettings.setIcon(icon);
}
}

You just have to put all the components you want to hide/show in a LayeredPane.

Java : Can't display JPanel above a JLabel with image

If you want the buttons to appear over plain images, then you have one of two options:

  • Draw the images in a paintComponent override in the main JPanel and not as ImageIcons within a JLabel. This will allow you to add components to this same JPanel, including buttons and such, and the images will remain in the background. If you go this route, be sure to call the super.paintComponent(g); method first thing in your override.
  • Or you could use a JLayeredPane (regardless of your not wanting to do this). You would simply put the background JPanel into the JLayeredPane.DEFAULT_LAYER, the bottom layer (constant is Integer 0), and place the newly displayed JButton Panel in the JLayeredPane.PALETTE_LAYER, which us just above the default. If you go this route, be sure that the added JPanel is not opaque, else it will cover over all images completely.

For an example of the 2nd suggestion, please see below:

import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;

public class JPanelControler {

private MyJPanel myJpanel;

public JPanelControler() {
myJpanel = new MyJPanel();
myJpanel.createJLabel();
myJpanel.getButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myJpanel.displayJPanel();
}
});
}

public MyJPanel getMyJpanel() {
return myJpanel;
}

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("test");
frame.setSize(900, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);

JPanelControler ctrl = new JPanelControler();

frame.add(ctrl.getMyJpanel());
frame.setVisible(true);
}
}

class MyJPanel extends JLayeredPane {

private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia"
+ "/commons/thumb/f/fc/Gros_Perr%C3%A9.jpg/100px-Gros_Perr%C3%A9.jpg";
private JButton button;
private ArrayList<JLabel> labels;
// a JPanel that contains buttons,... I won't put this class here
private JPanel panel;

public MyJPanel() {
setLayout(null);
button = new JButton("X");
button.setBounds(600, 600, 50, 50);
add(button, JLayeredPane.DEFAULT_LAYER); // add to the bottom
}

public void createJLabel() {
labels = new ArrayList<>();
JLabel label;
try {
URL imgUrl = new URL(IMG_PATH); // ** added to make program work for all
BufferedImage image = ImageIO.read(imgUrl);
for (int i = 0; i < 2; i++) {
label = new JLabel(new ImageIcon(image));
label.setBounds(i * 100, 50, image.getWidth(), image.getHeight());
labels.add(label);
add(label);
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void displayJPanel() {
panel = new JPanel();
panel.setLayout(null);
panel.setOpaque(false); // ** make sure can see through
JButton b = new JButton("Ok");
b.setBounds(0, 0, 100, 50);
JButton b2 = new JButton("Cancel");
b2.setBounds(0, 50, 100, 50);
panel.setBounds(150, 50, 100, 100);
panel.add(b);
panel.add(b2);
add(panel, JLayeredPane.PALETTE_LAYER); // add it above the default layer
refresh();
}

public void refresh() {
// invalidate(); // not needed
revalidate();
repaint();
}

public JButton getButton() {
return this.button;
}
}


Related Topics



Leave a reply



Submit