I want to add a JScrollPane to a JPanel. I have added some more code to this old question of mine.
I have a Panel class as follows:
import java.awt.*;
import javax.swing.JPanel;
public class Panel extends JPanel
{
public Panel()
{
super (true);
}
public void paintComponent (Graphics g)
{
super.paintComponent(g);
setBackground(Color.WHITE);
g.drawRect(250, 250, 10, 10);
}
}
and a JScrollPaneTest class as follows:
import javax.swing.*;
public class JScrollPaneTest extends JFrame
{
Panel panel = new Panel();
public JScrollPaneTest ()
{
super("Test JScrollPane");
add(new JScrollPane(panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS));
setSize(300,300);
setVisible(true);
}
public static void main (String[] args)
{
JScrollPaneTest test = new JScrollPaneTest();
test.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
I have drawn a small rectangle in the lower right corner on the Panel; apparently the JScrollPane does not work because when resizing the rectangle disappears.
Please let me know if you have any suggestions; thanks!
Related
I'm fairly new to swing, so I'm not sure how a lot of this works. I'm trying to add a JPanel into a JFrame. Just to get a feel for the basics, I'm just printing a horizontal line and the text "Hello World" on top.
import javax.swing.*;
import java.awt.Color;
import java.awt.Graphics;
public class GUI extends JFrame{
public GUI() {
setTitle("Frame");
setSize(500, 500);
setBackground(Color.black);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
}
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.drawLine(0, 250, 500, 250);
}
public static void main(String[] args) {
GUI g = new GUI();
JPanel panel = new JPanel();
JLabel label = new JLabel();
panel.setSize(500, 500);
panel.setBackground(Color.black);
label.setText("Hello World");
label.setForeground(Color.green);
panel.add(label);
g.add(panel);
}
}
For some reason, I can't get the JPanel to display.
I am making a small app, but i want to set an image as background at the whole window. I tried to make this like below but nothing happen. The image is in the folder where the class is so as a path I put only the name...Can you help me please? what can I do?
Container c = getContentPane();
setContentPane(c);
setContentPane(new JLabel(new ImageIcon("Chrysanthemum.jpg")));
One possibility is to add a BorderLayout to the JFrame, which should fill the JFrame with the JLabel, then set the background, adding the JLabel to the frame and then add components to it, like this:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Foo extends JFrame {
public Foo() {
setLayout(new BorderLayout());
JLabel background = new JLabel(new ImageIcon("Untitled.png"));
add(background);
background.setLayout(new FlowLayout());
background.add(new JButton("foo"));
setSize(500, 500);
setVisible(true);
}
public static void main(String[] args) {
Foo foo = new Foo();
}
}
The above works for me, with the JButton at the top center of the 500 by 500 JFrame with the specified background.
What I would do is create a JPanel with a background image, and add it to the JFrame. I already have a BackgroundPanel class right in one of my projects, and this is the setup I have for it.
public class MyFrame extends JFrame {
private BackgroundPanel bgPanel;
public MyFrame() {
bgPanel = new BackgroundPanel("Chrysanthemum.jpg");
setTitle("MyFrame");
setResizable(false);
setContentPane(bgPanel);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new MyFrame();
}
}
// -- BackgroundPanel class
public class BackgroundPanel extends JPanel {
private static final long serialVersionUID = 1L;
private Image bg;
public BackgroundPanel(String path) {
this(Images.load(path).getImage());
}
public BackgroundPanel(Image img) {
this.bg = img;
setPreferredSize(new Dimension(bg.getWidth(null), bg.getHeight(null)));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg != null) g.drawImage(bg, 0, 0, getWidth(), getHeight(), null);
}
}
Can anyone tell me why the rectangle is not showing up on the frame?
I only see a button on the frame. Please help.
I tried to using the paint method for drawing the rectangle.
Should I use paintComponent() or just paint()?
public class GUI2 {
public static void main(String[] args) {
JFrame frame = new JFrame("Game");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocation(500, 200);
JPanel panel = new JPanel();
frame.add(panel);
JButton button = new JButton("YO");
panel.add(button);
button.addActionListener(new Action());
frame.paint(null);
}
public void paint(Graphics g) {
g.drawRect(250, 250, 200, 100);
}
static class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
}
}
}
You shouldn't have to explicitly call paint
get rid of the paint method
Make an Inner JPanel class
Yes override paintComponent in the JPanel class
Call super.paintComponent in the paintComponent method.
Add the class JPanel to the JFrame
Don't do everything inside the main, as you'll find out, that static will cause a problem for you. Do everything inside a constructor
Run the program from the EDT SwingUtilitites.invokeLater().
Make the button a global variable so it can be accessed from the ActionListener
setVisible should be the last thing you do, after adding all the component.
When adding multiple components the JFrame you will want to use the BorderLayout positions, or set the layout to the JFrame to something else besides BorderLayout
Override getPrefferedSize in your JPanel when painting, so the JPanel has a respected preferred size.
Don't set the size of the JFrame just call pack();
Here is a refactor of your code
Also see Creating GUI with Swing | Graphics2D | Performing Custom Paintin for further details.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class GUI2 {
JButton button = new JButton("YO");
public GUI2() {
button.addActionListener(new Action());
JFrame frame = new JFrame("Game");
frame.add(new DrawPanel(), BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(250, 250, 200, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GUI2();
}
});
}
static class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
}
}
}
I can tell you why you'll get a NullPointerException
You've not overridden any paint method of any displayable component
You've not passed a valid Graphics context to you paint method, but I would discourage this any way
You should make use of the #Override annotation which would have prevented the class from compiling. Use it when you think you're overriding a method of a parent class, it will tell you when you're wrong
Start by taking a look at Performing Custom Painting and then take a look at Painting in AWT and Swing for more details about how painting is actually done in Swing
Here is working example of your code:
package test;
import javax.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.ImageObserver;
import java.awt.*;
import java.text.AttributedCharacterIterator;
public class GUI2 extends JPanel{
JButton button;
JFrame frame;
public GUI2() {
button = new JButton("YO");
//panel = new JPanel();
frame = new JFrame();
//panel = new JPanel();
this.add(button);
frame.add(this);
//button.addActionListener(new Action());
// this.paint(null);
frame.setSize(500, 500);
frame.setLocation(500, 200);
frame.setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawRect(250, 250, 200, 100);
}
public static void main(String[] args) {
GUI2 test = new GUI2();
}
}
I have removed some statements but you can add them later
I have a following code ( trying to learn swing and java). I created a ladder using rectangular components using class and placed on the main frame. Everything works okay but if I resize it even slightly, the ShapeManager object (i.e, the ladder) disappears. I don't know what is going on. Any help please.
GUIMain Class:
package mainProg;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.*;
public class GUIMain {
static JPanel mainPanel;
static JButton[] newButtons;
static ShapeManager newShape;
private static class BtnEvtHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//System.exit(0);
JOptionPane.showMessageDialog( null, "WELCOME" );
}
}
private static JButton[] createButtons() {
JButton[] buttonArray= new JButton[2];
buttonArray[0]=new JButton("OK");
buttonArray[1]=new JButton("MOVE");
BtnEvtHandler okButtonHandler= new BtnEvtHandler();
( buttonArray[0]).addActionListener(okButtonHandler);
return buttonArray;
}
private static ShapeManager createShape(int x) {
ShapeManager newContent=new ShapeManager(x);
return newContent;
}
private static JPanel mainContainer() {
JPanel mainPanel= new JPanel();
mainPanel.setSize(400, 400);
return mainPanel;
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(false);
JFrame frame = new JFrame(" DB ");
mainPanel= mainContainer();
mainPanel.setLayout(new BorderLayout(10, 10));
newButtons= createButtons();
newShape= createShape(20);
newButtons[0].setHorizontalAlignment(0);
mainPanel.add(newButtons[0],BorderLayout.PAGE_START);
newButtons[1].setHorizontalAlignment(0);
mainPanel.add(newButtons[1],BorderLayout.PAGE_END);
newShape.setPreferredSize(new Dimension(400, 400));
mainPanel.add(newShape, BorderLayout.LINE_END);
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocation(500,200);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
ShapeManager Class:
package mainProg;
import javax.swing.JPanel;
import java.awt.*;
#SuppressWarnings("serial")
class ShapeManager extends JPanel {
int rectPos;
ShapeManager(int rectPos) {
setPreferredSize(new Dimension(400,400));
this.rectPos=rectPos;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
while (rectPos<150) {
g.setColor(Color.BLUE);
g.drawRect(rectPos+10, rectPos+10, 100, 10);
g.fillRect(rectPos+10, rectPos+10, 100, 10);
rectPos=rectPos+10;
}
}
}
You never reset rectangle position, so after the first paint it remains above 150. You need to reset it after you exit your while loop.
Try this:
g.setColor(Color.BLUE);
int position = rectPos;
while (position<150) {
position += 10;
g.drawRect(position, position, 100, 10);
g.fillRect(position, position, 100, 10);
}
I have a JScrollPane and on top of it I have a JPanel named 'panel1'.
I want some rectangles to be drawn on this JPanel.
I have a class named DrawRectPanel which extends JPanel and does all the drawing stuff.
The problem is that, I tried to draw the rectangles on panel1 by writing the following code :
panel1.add(new DrawRectPanel());
but nothing appeared on panel1
then I tried, just as a test to the class DrawRectPanel :
JFrame frame = new JFrame();
frame.setSize(1000, 500);
Container contentPane = frame.getContentPane();
contentPane.add(new DrawRectPanel());
frame.show();
This worked, and produced the drawings but on a separate JFrame
How can I draw the rectangles on panel1 ?
Thanks in advance.
EDIT :
code for DrawRectPanel
public class DrawRectPanel extends JPanel {
DrawRectPanel() {
Dimension g = new Dimension(400,400);
this.setPreferredSize(g);
System.out.println("label 1");
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("label 2");
g.setColor(Color.red);
g.fillRect(20, 10, 80, 30);
}
}
only label 1 is printed on the screen
still no idea,
for example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class CustomComponent extends JFrame {
private static final long serialVersionUID = 1L;
public CustomComponent() {
setTitle("Custom Component Graphics2D");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void display() {
add(new CustomComponents());
pack();
// enforces the minimum size of both frame and component
setMinimumSize(getSize());
setVisible(true);
}
public static void main(String[] args) {
CustomComponent main = new CustomComponent();
main.display();
}
}
class CustomComponents extends JComponent {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
#Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}
instead of adding
contentPane.add(new DrawRectPanel());
you should do
contentPane.add(panel1);
Because you already have new DrawRectPanel in panel1. But in your code you are adding another instance of DrawRectPanel in contentPane. And never added panel1 in none of your container.
to fix your problem, change "paintComponent" to "paint" when the window repaints automatically, it should work.