JScroll Pane not visible in JPanel.[JAVA] - java

I am trying to add scrollbar to panel2 in the following code which contains an image in it. The problem is even though i add JScrollPane, i am getting no scrollbar in the output and it doesn't scroll either and i only see half of the image. Please help .
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.awt.image.*;
public class manga extends JPanel{
public static void main(String[] args) {
JFrame frame = new JFrame("Swing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel=new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
JPanel panel1=new JPanel();
JPanel panel2=new JPanel();
JButton button1=new JButton("PlAY");
button1.setBounds(100,300,70,30);
String path="01.jpg";
ImageIcon imageIcon = new ImageIcon(path);
JLabel label = new JLabel(imageIcon);
panel.setPreferredSize(new Dimension(1000,1000));
JScrollPane scroll = new JScrollPane(label);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel2.add(scroll);
panel2.add(label);
panel1.setBackground(new Color(255,255,255));
panel2.setBackground(new Color(0,0,0));
panel1.add(button1);
panel.add(panel1);
panel.add(panel2);
frame.add(panel);
frame.setTitle("MANGA READER 0.1");
frame.setSize(1366,768);
frame.setVisible(true);
}
}
I think the error lies in the following code.
panel.setPreferredSize(new Dimension(1000,1000));
JScrollPane scroll = new JScrollPane(label);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel2.add(scroll);
I am not sure.Please help

In Java Swing a component can have only one parent.
That means that by executing
panel2.add(scroll);
panel2.add(label);
you remove the label from the scroll pane.
Your don't need to add the label to the panel itself, so just drop that line and write only
panel2.add(scroll);

Related

Is there an option to add ScrollPane without disabling CardLayout?

I have a card layout where I switch panels with a button. However, the code (switching panels) works only when lines:
JScrollPane scrPane = new JScrollPane(card1);
frame.add(scrPane);
are removed. In other case, clicking button achieves nothing. Is there an option to keep the scrolling (I need this, since the main application will have a lot of wrapped text) without disabling an option to switch cards?
package com.code;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.event.*;
public class Card {
public static void main(String[] args) {
JFrame frame = new JFrame("App");
frame.setVisible(true);
frame.setSize(1200, 800);//Give it a size
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel(new CardLayout());
frame.add(mainPanel);
JPanel menu = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
mainPanel.add(menu, "menu");
mainPanel.add(card1, "card1");
mainPanel.add(card2, "card2");
JLabel l1 = new JLabel("label 1");
JLabel l2 = new JLabel("label 2");
card1.add(l1);
card2.add(l2);
JButton click = new JButton("Click!");
menu.add(click);
JScrollPane scrPane = new JScrollPane(card1);
frame.add(scrPane);
click.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout cardLayout = (CardLayout) mainPanel.getLayout();
cardLayout.show(mainPanel, "card1");
}
});
}
}
A JFrame (its content pane) uses BorderLayout by default. That means you can have only 1 component at BorderLayout.CENTER. When you frame.add(component) the default constraints is BorderLayout.CENTER.
Now, you frame.add(mainPanel); and then frame.add(scrPane);. So main panel is removed, since scrPane is being added after it.
Doing JScrollPane scrPane = new JScrollPane(card1); it means you add a scrollpane to card1, and not in content pane. I guess that you want it to the content pane (the whole frame). So the fix is to delete frame.add(mainPanel); and do the following:
JScrollPane scrPane = new JScrollPane(mainPanel);
frame.add(scrPane);
Now, the main panel is added to scrPane and scrPane is added to the frame.
However, your GUI will be empty after that, because you frame.setVisible(true); before you are finished adding components to it. Take a look at Why shouldn't I call setVisible(true) before adding components?
Eventually, full code is:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("App");
frame.setSize(1200, 800);//Give it a size
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel(new CardLayout());
JPanel menu = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
mainPanel.add(menu, "menu");
mainPanel.add(card1, "card1");
mainPanel.add(card2, "card2");
JLabel l1 = new JLabel("label 1");
JLabel l2 = new JLabel("label 2");
card1.add(l1);
card2.add(l2);
JButton click = new JButton("Click!");
menu.add(click);
JScrollPane scrPane = new JScrollPane(mainPanel);
frame.add(scrPane);
click.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout cardLayout = (CardLayout) mainPanel.getLayout();
cardLayout.show(mainPanel, "card1");
}
});
frame.setVisible(true);
});
}
Some good links I suggest you to read are the Initial Threads and What does .pack() do?

Having Multiple Panels with scroll panes

I created two panels and a main panel. Each panel contains a very large image, and I wanted both of them to be scroll-able to see the rest of the image. But when I add the two panels in the main panel and run it, the first panel is soo big that it covers the second panel. How would I implement ScrollPane for both panels?
import java.awt.BorderLayout;
import javax.swing.*;
public class BoardFrame extends JFrame {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel jLabel = new JLabel();
JPanel jPanelNorth = new JPanel();
JScrollPane scrollPane = new JScrollPane();
JLabel jLabel2 = new JLabel();
JPanel jPanelSouth = new JPanel();
JScrollPane scrollPane2 = new JScrollPane();
public BoardFrame() {
jLabel.setIcon(new ImageIcon("an image here"));
jPanelNorth.add(jLabel);
jLabel2.setIcon(new ImageIcon("an image here"));
jPanelSouth.add(jLabel2);
mainPanel.add(jPanelNorth, BorderLayout.NORTH);
mainPanel.add(jPanelSouth, BorderLayout.SOUTH);
add(mainPanel);
//where would I use this?
//scrollPane.setViewportView();
}
}
Each panel contains a very large image>
//JPanel mainPanel = new JPanel(new BorderLayout());
JPanel mainPanel = new JPanel(new GridLayout(0, 1));
You may want to use a GridLayout so that each scroll pane takes up half the frame so as much of each image as possible is displayed.
//JScrollPane scrollPane = new JScrollPane();
JScrollPane scrollPane2 = new JScrollPane(jPanelNorth);
The easiest way to use the scroll pane is to create the scrollpane with the component you want displayed and the scrollpane will add the component to the viewport for you.
//mainPanel.add(jPanelNorth, BorderLayout.NORTH);
mainPanel.add(scrollPane); // don't need the constraint when using GridLayout.
Then you add the scrollPane to the main panel, since the scrollpane contains the panel with the image.
it seems to use grid layout is much better than using border layout , in this case :
import java.awt.BorderLayout;
import javax.swing.*;
public class BoardFrame extends JFrame {
//1. use GridLayout with 2 rows and 1 column .
JPanel mainPanel = new JPanel(new GridLayout(2,1));
JLabel jLabel = new JLabel();
JPanel jPanelNorth = new JPanel();
JScrollPane scrollPane = new JScrollPane();
JLabel jLabel2 = new JLabel();
JPanel jPanelSouth = new JPanel();
JScrollPane scrollPane2 = new JScrollPane();
public BoardFrame() {
jLabel.setIcon(new ImageIcon("an image here"));
jPanelNorth.add(jLabel);
jLabel2.setIcon(new ImageIcon("an image here"));
jPanelSouth.add(jLabel2);
//2.you should place .setViewportView() here :
scrollPane.setViewportView(jPanelNorth);
scrollPane2.setViewportView(jPanelSouth);
mainPanel.add(scrollPane);//is in the top ("North")
mainPanel.add(scrollPane2);//next ("South")
//3.use setContentPane instead of add()
setContentPane(mainPanel);
}
}

JPanel with FlowLayout not Appearing

I am using the following code for placing labels inside a JPanel, but the JPanel is not appearing (instead, only a blank JFrame is appearing).
Below is the class creating a JFrame instance.
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args){
WindowContents window = new WindowContents();
window.setSize(600, 400);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Below is the class for setting the contents of the JFrame.
import javax.swing.*;
import java.awt.*;
public class WindowContents extends JFrame {
JLabel label1;
JLabel label2;
JLabel label3;
JPanel panel1;
public WindowContents(){
super("Label Display 2.0");
panel1 = new JPanel();
panel1.setLayout(new FlowLayout(FlowLayout.CENTER, 40, 40));
panel1.setVisible(true);
label1 = new JLabel("Label1");
panel1.add(label1);
label2 = new JLabel("Label2");
panel1.add(label2);
label3 = new JLabel("Label3");
panel1.add(label3);
}
}
Are there any ideas how to make the JPanel contents appear? Thank you.
how to make the JPanel contents appear?
Add panel in the frame.
public WindowContents(){
super("Label Display 2.0");
panel1 = new JPanel();
...
add(panel1);
}
Note:
Use frame.pack() instead of frame.setSize() that fits the components as per component's preferred size.
There is no need to call panel1.setVisible(true);
Just call frame.setVisible(true) in the end after adding all the component.
Favor Composition over inheritance. Instead of extending JFrame make it as member of WindowContents class.
Use SwingUtilities.invokeLater() or EventQueue.invokeLater() to make sure that EDT is initialized properly.
you haven't added the panel to the frame, here's how your class WindowsContents end:
class WindowContents extends JFrame {
JLabel label1;
JLabel label2;
JLabel label3;
JPanel panel1;
public WindowContents(){
super("Label Display 2.0");
panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 40, 40));
label1 = new JLabel("Label1");
panel1.add(label1);
label2 = new JLabel("Label2");
panel1.add(label2);
label3 = new JLabel("Label3");
panel1.add(label3);
add(panel1);
}
}
Cheers

Getting Labels a name with a label

This panel class is suppose to print out "Course Info" Yet when I do try to print it out on the GUI, the gui frame shows up but not the Panel. So I feel the panel code is the problem, how to get the "Course Info" to appear? And if the label is working correctly, why when I post the label to the gui, it just shows another blank Frame?
Panel:
import javax.swing.*;
import java.awt.*;
public class TopPanel extends JPanel {
public TopPanel(){
JPanel panel = new JPanel();
JLabel Crse = new JLabel("Course Info");
Crse.setFont(new Font("Serif", Font.PLAIN, 14));
panel.add(Crse);
}
}
GUI code:
import javax.swing.*;
import java.awt.*;
public class CourseGUI extends JFrame {
public CourseGUI()
{
super("CourseGUI Frame");
JPanel topPanel = new JPanel();
topPanel.setBackground(java.awt.Color.WHITE);
Dimension d = new Dimension(800,600);
topPanel.setPreferredSize(d);
this.setLayout(new BorderLayout());
this.add(topPanel, BorderLayout.NORTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800,600);
//JPanel tp = new TopPanel();
//this.add(tp.BorderLayout.North);
JPanel panel = new TopPanel();
this.add(panel, BorderLayout.SOUTH);
this.setVisible(true);
}
public static void main(String[] args)
{
new CourseGUI();
}
}
Try like this
public TopPanel(){
JLabel Crse = new JLabel("Course Info");
Crse.setFont(new Font("Serif", Font.PLAIN, 14));
add(Crse);
}
You are creating new JPanel which will not going to get added in JFrame.
As you are doing this.
this.add(topPanel, BorderLayout.NORTH);
for JFrame but topPanel don't have anything to display because you didn't add anything.

Java: vertical alignment within JPanel

I am trying to vertically align (center) both JLabels inside one JPanel.
JPanel panel = new JPanel();
panel.setPreferredSize(size);
JLabel label1 = new JLabel(icon);
JLabel label2 = new JLabel("text");
panel.add(label1);
panel.add(label2);
I have tried using setAligmentY() with no success. Both labels always appear on the top of JPanel.
UPD: Labels should be located next to each other like using FlowLayout, but in the middle of the JPanel.
Use a GridBagLayout with the default constraints. Here is a small demo code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestVerticalAlignement {
protected void initUI() {
final JFrame frame = new JFrame();
frame.setTitle("Test vertical alignement");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JLabel label1 = new JLabel("label1");
JLabel label2 = new JLabel("label2");
panel.add(label1, gbc);
panel.add(label2, gbc);
frame.add(panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestVerticalAlignement().initUI();
}
});
}
}
you can see this answer:
https://stackoverflow.com/a/18073909/189411
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
Use gridlayout, simple.
That should work.
Consider my following example:
import java.awt.*;
import java.applet.Applet;
import javax.swing.*;
/*
<applet code=AJ07 width=450 height=450>
</applet>
*/
public class AJ07 extends JApplet{
Container c=null;
public void init(){
JPanel pTop=new JPanel();
JPanel pLeft=new JPanel();
JPanel pCenter=new JPanel();
JPanel pProperties=new JPanel();
pLeft.setLayout(new GridLayout(20,1));
c=this.getContentPane();
JButton bNew=new JButton("New");
pTop.add(bNew);
JButton bOpen=new JButton("Open");
pTop.add(bOpen);
JButton bSave=new JButton("Save");
pTop.add(bSave);
JButton bSaveAll=new JButton("Save All");
pTop.add(bSaveAll);
JButton bRun=new JButton("Run");
pTop.add(bRun);
JButton bStop=new JButton("Stop");
pTop.add(bStop);
JButton bPause=new JButton("Pause");
pTop.add(bPause);
JButton bText=new JButton("TextBox");
pLeft.add(bText);
JButton bButton=new JButton("Button");
pLeft.add(bButton);
pProperties.setLayout(new GridLayout(20,1));
pProperties.add(new Label("BackColor"));
pProperties.add(new Label("ForeColor"));
c.add(new TextArea(),BorderLayout.CENTER);
c.add(pTop,BorderLayout.NORTH);
c.add(pLeft,BorderLayout.WEST);
c.add(new Label("Project Loaded Successfully!"),BorderLayout.SOUTH);
c.add(pProperties,BorderLayout.EAST);
//c.add(pCenter,BorderLayout.CENTER);
}
}
for which the output is as follows:

Categories