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.
Related
So basically when I add a button it essentially pushes the black rectangle drawn in this program down, putting it out of its given location. How would you fix this?
import javax.swing.*;
import java.awt.*;
public class Grid {
public class homeGraphics extends JComponent {
homeGraphics() {
setPreferredSize(new Dimension(450, 600));
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(200, 275, 50, 50);
}
}
public void homeFrame() {
JFrame frame1 = new JFrame();
frame1.setSize(450, 600);
frame1.setResizable(false);
frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
JButton playButton = new JButton("Play");
playButton.setPreferredSize(new Dimension(60, 30));
JPanel panel1 = new JPanel();
panel1.add(playButton);
panel1.add(new homeGraphics());
frame1.add(panel1);
frame1.setVisible(true);
}
public static void main(String args[]) {
Grid frame = new Grid();
frame.homeFrame();
}
}```
it essentially pushes the black rectangle drawn in this program down, putting it out of its given location.
What do you mean out of its location? Painting is always done relative to the component. So your painting will always be done at (200, 275) of the component.
If you are attempting to paint at (200, 275) relative to the "frame", then don't. That is NOT how painting works.
Other problems with your code:
Don't attempt to set the size of your frame. If the custom panel is (450, 600) how can the frame possibly be the same size? The frame also contains the "title bar" and "borders". Instead of using setSize(), you invoke frame.pack()just beforeframe1.setVisible(….)`.
Class names start with an upper case character. Learn by example. Have you ever seen a class name in the JDK that doesn't start with an upper case character?
Custom painting is done by overriding paintComponent(…), not paint().
By default a JPanel uses a FlowLayout. So what you see it the button on one line and then the "HomeGraphics" class is too big to fit on the same line so it wraps the to the second line.
You should be more explicit when you do frame layout. So your code should be something like:
JPanel wrapper = new JPanel();
wrapper.add( playButton );
//JPanel panel1 = new JPanel();
//panel1.add(playButton);
//panel1.add(new homeGraphics());
JPanel panel1 = new JPanel( new BorderLayout() );
panel1.add(wrapper, BorderLayout.PAGE_START);
panel1.add(new HomeGraphics(), BorderLayout.CENTER);
Now the code shows your layout attempt more clearly.
My GUI consists of a Diagram class which extends JFrame. I've created a different class called DrawingTool which extends JComponent. The DrawingTool class is like a canvas area for users to drop and drag shapes. I've also added a button panel at the bottom of the JFrame for the users to click various buttons to choose their desired shape and control actions. I've added the button panel and an instance of the DrawingTool class to the Diagram class. How do I make the canvas area (DrawingTool) scrollable? The way I have attempted it is not working, I know I am missing something.
Here is the Diagram class:
public class Diagram extends JFrame {
JButton serverButton, vipButton, arrowButton, undoButton, dragButton, loadButton, submitButton;
JButton applicationButton;
int currentAction = 1;
Graphics2D graphSettings;
Color strokeColor = Color.BLUE, fillColor = Color.BLACK;
/**
* Constructor to generate new diagram with empty drawing board and button
* panel.
*/
public Diagram() {
// Define the defaults for the JFrame
this.setSize(1000, 1000);
this.setTitle("Diagram Tool");
//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonPanel = new JPanel();
// Swing box that will hold all the buttons
Box theBox = Box.createHorizontalBox();
// Make all the buttons in makeButtons by calling helper function
serverButton = makeButtons("Server", 2);
vipButton = makeButtons("VIPs", 3);
arrowButton = makeButtons("Arrow", 4);
undoButton = makeButtons("Undo", 5);
dragButton = makeButtons("Drag", 6);
loadButton = makeButtons("Load", 11);
applicationButton = makeButtons("Application", 8);
submitButton = makeButtons("Submit", 12);
// Add the buttons to the box
theBox.add(serverButton);
theBox.add(vipButton);
theBox.add(applicationButton);
theBox.add(arrowButton);
theBox.add(undoButton);
theBox.add(dragButton);
theBox.add(loadButton);
theBox.add(submitButton);
// Add the box of buttons to the panel
buttonPanel.add(theBox);
// Position the buttons in the bottom of the frame
JPanel container=new JPanel();
container.add(new DrawingBoard(),BorderLayout.CENTER);
JScrollPane jsp=new JScrollPane(container);
this.add(buttonPanel, BorderLayout.SOUTH);
this.add(jsp);
// Make the drawing area take up the rest of the frame
// Show the frame
this.setVisible(true);
}
Here is the DrawingBoard class:
private class DrawingBoard extends JComponent implements MouseListener, MouseMotionListener {
//declare variables
/**
* Constructor to initialize the drawing board
*/
public DrawingBoard() {
addMouseListener(this);
addMouseMotionListener(this);
// initializeCanvas();
}
//Rest of the code for DrawingBoard
}
This is how it looks now. I'd like to make the gray canvas area scrollable.
Diagram Image
What MadProgrammer said in the comments is just about right. You need to set some informations so your ScrollPanel knows how to behave. What is it's own size, the size of the components inside it, etc.
So normally you'll have a ContentPane, and inside of it panes with your content. To do a scrollable pane you only need to put the ScrollPane inside of your ContentPane and then set a viewport for your ScrollPane. A little code I used fully functional:
contentPane = new JPanel();
setContentPane(contentPane);
contentPane.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
//Vertical and Horizontal scroll bar policy is set to choose when the scroll will be visible scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(0, 217, 414, 505);
scrollPane.setPreferredSize(new Dimension(414, 414));
JPanel viewport = new JPanel();
viewport.setLayout(null);
viewport.setBounds(0, 0, 414, 505);
//Create your components here, then:
//viewport.add(component)
viewport.setPreferredSize(new Dimension(414, 150));
scrollPane.setViewportView(viewport);
contentPane.add(scrollPane);
Anything you put inside of your ViewPort
will be automaticaly scrolable, if it's size is bigger than the PreferredSize.
Note that all the dimensions I've put is only for example.
I have copy my code to display a text feild and a JSlider) from a project that usses a JFrame
My new project usses a JInternalFrame, and only the slider is drawn. If I comment out the code it will draw the text field, seems like it only wonts to draw 1 control.
code
JPanel containerPanel = new JPanel(new BorderLayout() );
cDrawComponent mDrawComponent = new cDrawComponent();
containerPanel.add(mDrawComponent,BorderLayout.CENTER);
JLabel mJLabel=new JLabel("000");
mJSlider = new JSlider(JSlider.HORIZONTAL, 0, 1000,500);
JPanel sliderPanel = new JPanel(new BorderLayout() );
// TRYING TO ADD 2 CONPOMENTS ONLY SLIDER IS SHOWN
sliderPanel.add(mJLabel);
sliderPanel.add(mJSlider);
containerPanel.add(sliderPanel,BorderLayout.SOUTH);
class SliderListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
ted++;
if (!source.getValueIsAdjusting()) {
{
sliderPes = (int) source.getValue();
int max=source.getMaximum();
scrollPes=max-sliderPes;
repaint();
}
}
}
}
mJSlider.addChangeListener(new SliderListener());
add(containerPanel);
Use
sliderPanel.add(mJLabel, BorderLayout.WEST);
The BorderLayout can show only one component at the center (Default, if ommited). That's usually the last one, that got added.
First of all: sorry, if this question was asked before, but I cannot seem to find an answer anywhere, so here we go:
I am trying to get a canvas element to show while it being added to a panel with a titled border around the panel. Here is my code.
public class TestClass extends JFrame{
private TestClass() {
GuiCanvas canvas = new GuiCanvas();
setTitle("TestClass");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1300, 800);
Border menuBorder = BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.LIGHT_GRAY), "Overview");
JPanel controlpanel = new JPanel();
JPanel panelCanvas = new JPanel();
panelCanvas.setBorder(menuBorder);
panelCanvas.add(canvas);
controlpanel.setLayout(new GridLayout(3, 1));
controlpanel.add(panelCanvas);
add(controlpanel);
setLocationRelativeTo(null);
setVisible(true);
System.out.println(canvas.getBounds());
}
private class GuiCanvas extends Canvas {
GuiCanvas() {
setBackground(Color.LIGHT_GRAY);
}
#Override
public void paint(Graphics g) {
g.drawLine(20, 20, 20, 200);
}
}
public static void main(String[] args) {
new TestClass();
}
}
The above code results in an empty panel with a titled border when it should show the defined line I draw in the GuiCanvas-Class. Am I missing something here? Is it even possible to add a canvas-element to a panel? Thanks for your help in advance :)
If you want the canvas to stretch to the size of the panel, change:
JPanel panelCanvas = new JPanel();
To:
JPanel panelCanvas = new JPanel(new GridLayout());
See also this answer:
It is indeed possible to add a Canvas object to a JPanel.
Your problem lies in the fact that your Canvas has no defined size.
What you need are the two following lines
canvas.setPreferredSize(new Dimension(1300,300));
/*
*
*/
this.pack();
This will place your canvas inside the panelCanvas border, displaying a black vertical line on a light gray background.
I have the following code to create my GUI.
private static void createGUI() {
JFrame frame = new JFrame ("Tiles Game");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar (new JMenuBar());
frame.setContentPane (MainPanel.getInstance());
frame.pack();
frame.setResizable (false);
frame.setLocationRelativeTo (null);
frame.setVisible (true);
}
This is the MainPanel (extends JPanel) constructor:
private MainPanel() {
super (new BorderLayout());
setPreferredSize (new Dimension (IMG_SIZE + 10, IMG_SIZE + 10));
...
panel = new ImagePanel();
add (panel, BorderLayout.CENTER);
}
And this is the ImagePanel (extends JPanel) constructor:
private ImagePanel() {
super();
setPreferredSize (new Dimension (IMG_SIZE, IMG_SIZE));
...
}
However the ImagePanel is aligned to the top left corner of the MainPanel rather than centered, so I get a bunch of extra padding at the bottom and right sides, and none at the top and left sides. How do I place it at the center of the MainPanel?
Probably what's happening is that you are drawing your image from (0, 0) which are the top-left corner. Then you set the preferred size to 10 pixels larger which makes the panel larger, but the image is still at (0, 0)
Instead use the same size witoout adding 10, and just use an EmptyBorder for the panel. Also as a recommendation, override getPreferredSize() instead of using setPreferredSize()
public class ImagePanel extends JPanel {
public ImagePanel() {
setBorder(new EmptyBorder(10, 10, 10, 10));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(IMG_SIZE, IMG_SIZE);
}
}
Also you may want to consider using a GridBagLayout for the container panel, for a sure center, if the container is to be larger than the the child panel. Few things you could do. Even consider using a ImageIcon and JLabel instead of painting (if the image doesn't need to be resized (as Camickr(+1) pointed out). A JLabel could easily be made a background by just setting the layout of the label and set it as the content pane of the frame.
ImageIcon icon = new ImageIcon(...)
JLabel frameBackground = new JLabel(icon);
frameBackground.setLayout(new BorderLayout());
frame.setContentPane(frameBackground);
Don't use a JPanel to display an image.
Instead use a JLabel with an ImageIcon.
If you want extra space around the image then you use an EmptyBorder on the label.