How can I place JButton over a JLabel with image? - java

I use NetBeans IDE to create an application using java. I want to include a JButton over a JLabel with image. Actually when I add JButton over the JLabel it would inserted but it will transparent and the name and the button didn't display. It seems the button to be added under the JLabel. How can I overcome this problem?

there are two ways
put image to JPanel by override paintComponent (standard way)
JLabel haven't any LayoutManager in API, you have to set LayoutManager, then JLabel will be container

ImageIcon img = null;
class Panel extends JPanel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img == null){
img = new ImageIcon("d:\\picture.jpg");
g.drawImage(img.getImage(), 0, 0, null);
}
}
}
//in the constructor
JButton button = new JButton( "OK");
Panel panel = new Panel();
panel.add(button);
add(panel);

Related

JLabels not showing in JPanel if bounds not set

I have the following code:
public JPanel getPanel() {
if(jpanel == null) {
jpanel = new JPanel();
jpanel.setLayout(new FlowLayout());
jpanel.setBounds(x, y, width, height);
jpanel.setBackground(Color.WHITE);
JLabel tituloLbl = new JLabel(titulo);
JLabel cantidadLbl = new JLabel(""+cantidad);
JLabel abejasLbl = new JLabel("Abejas");
//tituloLbl.setBounds(0, 0, 50, 15);
jpanel.add(tituloLbl);
jpanel.add(cantidadLbl);
jpanel.add(abejasLbl);
}
return jpanel;
}
The panel should look like a small white box with 3 labels in it, however, the labels don't show unless I set their bounds. Why does this happen? If I'm setting a FlowLayout, the labels should be positioned automatically.
This is how the panel shows:
Solved it, I had to call panel.validate() on my main frame in order to show them.

JPanel background image doesn't apply to a JPanel inside it

I'm working on a simple registration window that appears when the java app opens.
It's a JFrame, that has a JPanel in it, which has text fields, labels, and another panel which also contains text fields and labels.
My problem is that the outside panel has a background image, but it doesn't apply to the panel inside it as seen here:
Here is the whole window code:
public void start() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame = new JFrame("Chat");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setMaximumSize(new Dimension((int)screenSize.getWidth()-1000, (int)screenSize.getHeight()-1000));
frame.setMinimumSize(new Dimension((int)screenSize.getWidth()/2-200,(int) screenSize.getHeight()/2));
frame.setResizable(false);
welcome = new LoginPanel();
welcome.setLayout(new BoxLayout(welcome, BoxLayout.Y_AXIS));
welcome.setBorder(BorderFactory.createEmptyBorder(50, welcome.getWidth()/2-500, 50, welcome.getWidth()/2 -500));
//repaintThread = new Thread(new RepaintRunnable(frame, welcome));
//repaintThread.start();
request = new JLabel("Please fill the required fields below:");
request.setFont(new Font("Serif", Font.BOLD, 20));
request.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
request.setAlignmentX(Component.CENTER_ALIGNMENT);
userInfo = new JPanel();
userInfo.setLayout(new BoxLayout(userInfo, BoxLayout.Y_AXIS));
userInfo.setAlignmentX(Component.CENTER_ALIGNMENT);
Font fieldType = new Font("Serif", Font.PLAIN, 15);
PlainDocument doc = new PlainDocument();
doc.setDocumentFilter(new NameDocument());
enterFirstName = new JLabel("First name:");
enterFirstName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterFirstName.setFont(fieldType);
firstName = new JTextField(20);
firstName.setMaximumSize(firstName.getPreferredSize());
firstName.setDocument(NameDocument.getNewNameDocument(NameDocument.NO_SPACE));
firstName.getDocument().addDocumentListener(new ChangeDocumentListener());
firstName.addActionListener(new ConfirmListener());
firstName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterSecName= new JLabel("Surname:");
enterSecName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterSecName.setFont(fieldType);
secName = new JTextField(30);
secName.setMaximumSize(secName.getPreferredSize());
secName.setDocument(NameDocument.getNewNameDocument(NameDocument.HAS_SPACE));
secName.getDocument().addDocumentListener(new ChangeDocumentListener());
secName.addActionListener(new ConfirmListener());
secName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterNickname = new JLabel("Nickname (how other people will see you in chat):");
enterNickname.setAlignmentX(Component.LEFT_ALIGNMENT);
enterNickname.setFont(fieldType);
nickname = new JTextField(30);
nickname.setMaximumSize(nickname.getPreferredSize());
nickname.setDocument(NameDocument.getNewNameDocument(NameDocument.NO_SPACE));
nickname.addActionListener(new ConfirmListener());
nickname.setAlignmentX(Component.LEFT_ALIGNMENT);
userInfo.add(enterFirstName);
userInfo.add(firstName);
userInfo.add(enterSecName);
userInfo.add(secName);
userInfo.add(enterNickname);
userInfo.add(nickname);
confirm = new JButton("Submit");
confirm.setAlignmentX(Component.CENTER_ALIGNMENT);
confirm.setEnabled(false);
confirm.addActionListener(new ConfirmListener());
welcome.add(request);
welcome.add(userInfo);
welcome.add(new Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
welcome.add(confirm);
frame.getContentPane().add(BorderLayout.CENTER, welcome);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
And here is the LoginPanel code(the outside JPanel):
public class LoginPanel extends JPanel {
public void paintComponent(Graphics g) {
try {
super.paintComponent(g);
BufferedImage background = ImageIO.read(new File("Background.jpg"));
g.drawImage(background, 0, 0, getWidth(), getHeight(), null);
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
it'll also be great if someone will give me advice on how to make this code better, since I'm beginner in Java.
Remember to call setOpaque(false); on any inner JPanels (and on some other components -- though not all) that cover up your image-displaying JPanel. This will allow background images to show through. You don't have to do this with JLabels as they are see-through (non-opaque) by default, but you do with JPanels.
So for you it will be:
userInfo = new JPanel();
userInfo.setOpaque(false);
One other problem is that you should never read in images from within a paintComponent method. This method may be called often, and why re-read the image when it can and should be read in only once. And more importantly, this method should be fast as possible since slowing it down needlessly will slow down the perceived responsiveness of your program. Read the image in once, and store it in a variable that is then displayed within paintComponent.
e.g.,
public class LoginPanel extends JPanel {
private BufferedImage background;
public LoginPanel(BufferedImage background) {
this.background = background;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
}
}
}
Read the image in and then pass it into the constructor of your LoginPanel class.
Not related to your problem but:
frame.getContentPane().add(BorderLayout.CENTER, welcome);
Since JDK 4 you don't need to use the getContentPane() method you can just use frame.add(...) and the component will be added to the content pane.
Also you are using the wrong add(...) method. You are using add(constraint, component). If you read the API for the method it will tell you to use the add(component, constraint) method.
So you could be using:
frame.add(welcome, BorderLayout.CENTER);

Adding JScrollPane to JPanel

I'm trying to add a JScrollPane to an JPanel from a separate class. And thanks to some questions, which were asked so far, I could help myself create them. But my problem is still a little bit special.
I want to display an image on a JPanel and if the image is to large for the panel, I want to add scrollbars. But the scrollbars won't appear.
(When I set the ScrollPaneConstants to ****_SCROLLBAR_ALWAYS the frame of the bar appears, but without the bars to scroll).
I guess i have to connect the imagesize with the bars, so that they appear?
Some pieces of my code:
MainWindow
public class Deconvolutioner extends JFrame
{
Draw z;
Picturearea picturearea;
class Draw extends JPanel
{
public void paint(Graphics g)
{
}
}
public Deconvolutioner()
{
setTitle("Deconvolutioner");
setLocation(30,1);
setSize(1300,730);
super.setFont(new Font("Arial",Font.BOLD,11));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
this.setLayout(flow);
picturearea = new Picturearea();
picturearea.setLayout(new GridBagLayout());
JScrollPane scrollPane = new JScrollPane(picturearea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(1000, 664));
getContentPane().add(scrollPane, flow); // add scrollpane to frame
add(z = new Draw());
setVisible(true);
}
}
JPanel Class
public class Picturearea extends JPanel
{
BufferedImage image;
int panelWidth, panelHeight, imageWidth, imageHeight;
public Picturearea()
{
setBackground(new Color(210,210,210));
setBorder(LineBorder.createBlackLineBorder());
setVisible(true);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
public void setPicture(BufferedImage picture)
{
try
{
image = picture;
}
catch (Exception e)
{
System.err.println("Some IOException accured (did you set the right path?): ");
System.err.println(e.getMessage());
}
repaint();
}
}
Thanks for your time.
The problem is that the JScrollPane has no way to know if it should display scroll bars or not, since the Picturearea it contains doesn't tell anything about its preferred size (or rather, it returns the preferred size based on its layout and on the components it contains. But since it doesn't contain any component, the returned preferred size is probably (0, 0)).
I would simply use a JLabel instead of the custom Picturearea class. A JLabel can display an image just fine, and it returns the appropriate Dimension when asked for its preferred size.
You can create a JLabel first and then add the Label to JPanel picturearea before creating instance for JScrollPane .
Have a try and it will work.
Example code is as follows:
JLabel imageLabel = new JLabel(new ImageIcon("d:\\099.jpg"));
picturearea.add(imageLabel);**
JScrollPane scrollPane = new JScrollPane(picturearea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

JPanel background image not getting changed

I am using following class for adding background image to JPanel.
http://www.java2s.com/Code/Java/Swing-JFC/Panelwithbackgroundimage.htm
But when the application is executing and image is changed the new updated image is not shown on screen.
Image image = new ImageIcon(path + item.getItemID() + ".png").getImage();
panel = new ImagePanel(image);
variable path is static path outside workspace.
If you "update JPanel with new JPanel" you are not "updating", you are creating a new JPanel.
Example, we have a green JPanel called "panelTest":
panelTest = new JPanel();
panelTest.setBackground(Color.green);
add(panelTest);
And now we have a button that will change the JPanel background color from green to red, but in a wrong way:
JButton btnTest = new JButton("Test");
btnTest.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panelTest = new JPanel(); //woops, now we have 2 panels...
panelTest.setBackground(Color.red);
}
});
Note that panelTest was a pointer to a green panel, and now it is pointing to a new JPanel with a red background. This new JPanel has not been added to any container, thus it will not be shown. And the old green panel will stay visible.
The best way to update the image is creating a method inside ImagePanel like:
public void setImage( Image image ) {
this.img = image;
this.repaint();
}
This way you don't have to create a new ImagePanel just for changing the background.

ImageLoading in JPanel using JFileChooser

I am trying to load an image into a JPanel using JFileChooser. But when I try to run the program and load a selected image nothing happens in the JPanel. I am attaching the source code snippet here:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileFilter filter = new FileNameExtensionFilter("Image files","jpeg","jpg");
fileChooser.setFileFilter(filter);
int result = fileChooser.showOpenDialog(null);
if(result == fileChooser.APPROVE_OPTION){
imgFile = fileChooser.getSelectedFile();//imgFile is File type
try{
myPicture = ImageIO.read(imgFile);//myPicture is BufferedImage
JLabel picLabel = new JLabel(new ImageIcon( myPicture )) ;
imagePanel.add( picLabel );
imagePanel.repaint();
System.out.println("You have selected "+imgFile);
}catch(Exception e){
e.printStackTrace();
}
}
}
Can anyone shed light on this?
The problem is that I have added two panels in my frame.
You might compare what you're doing with this complete example that uses two panels: a file chooser on the left and a display panel on the right.
I think this might help you...
Object selectedItem = jComboBox14.getSelectedItem();
ImageIcon picturetoInsert = new ImageIcon(selectedItem.toString());
JLabel label = new JLabel("", picturetoInsert, JLabel.CENTER);
JPanel panel = new JPanel(new GridLayout(1, 1));
panel.add(label, BorderLayout.CENTER);
jInternalFrame22.getContentPane();
jInternalFrame22.setContentPane(panel);
jInternalFrame22.setVisible(true);
Why don you try with the paint component?
class imagePanel extends JPanel
{
BufferedImage image;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(image != null)
{
g.drawImage(image, 0, 0, this);
}
}
}
There could be a few reasons for this. You could try
imagePanel.invalidate()
before the repaint call to force it to redraw.
Or possibly the label is to small and needs resizing since there may not have been an image before. You could try invoke the
frame.pack();
method to get the frame to recompute its component sizes.
Or you could try force the size of the label (setting its min size) to ensure it has enough space to show the image.

Categories