Reputation: 71
I am learning Java on my own. Trying to create a frame with a line in it. It seemed pretty basic, but I can't see the line. The code compiles and I can't seem to understand why I can't see the line. I see other components in the frame. I am using 2 java files. One file is container file and the other file has the draw line code. They are part of package a1. Here is my code (please help):
Container File:
package a1;
import javax.swing.*;
import java.awt.*;
public class gameContainer {
public static void addComponentsToPane(Container pane) {
pane.setLayout(null);
//add button to the pane
JButton b3 = new JButton("B1");
pane.add(b3);
//add line to the pane
drawingLine line1 = new drawingLine();
pane.add(line1);
//size and position all relatively
Insets insets = pane.getInsets();
Dimension size;
size = b3.getPreferredSize();
b3.setBounds(350+insets.left,15+insets.top,size.width+50,size.height+20);
size = line1.getPreferredSize();
line1.setBounds(350+insets.left,75+insets.top,size.width+50,size.height+20);
}
private static void createAndShowGUI() {
int l = 200, w = 80;
//Create and set up the window.
JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up content pane
addComponentsToPane(frame.getContentPane());
//add menu bar
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menu.add(new JMenuItem("Do nothing"));
menuBar.add(menu);
frame.setJMenuBar(menuBar);
// size and display root pane/window
Insets insets = frame.getInsets();
frame.setSize(500+insets.left+insets.right,300+insets.top+insets.bottom);
frame.setLocation(w,l);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Draw line File:
package a1;
import javax.swing.*;
import java.awt.geom.Line2D;
import java.awt.Graphics2D;
import java.awt.Graphics;
public class drawingLine extends JPanel{
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Line2D line = new Line2D.Double(200, 300, 1000, 1000);
//g2d.setColor(Color.black);
g2d.draw(line);
//g.drawLine(200, 300, 1000, 1000);
//g.setColor(color.BLACK);
}
}
Why am I not able to see the line?
Upvotes: 3
Views: 7970
Reputation: 5094
The proper (better to say, easier, much less error prone) way to do it has been shown by David Kroukamp. As for your original question, modify the original code like this:
line1.setBounds(350+insets.left,75+insets.top,size.width+50,size.height+20);
line1.setBorder(BorderFactory.createEtchedBorder()); // add this line
Your line starts at point 200,300 but the panel you're drawing it in has width of 50+10 and height of 20+10 - on my computer at least - which means that the line is outside of the drawingLine
panel and that's why it doesn't get drawn. To verify that modify the line in your original drawingLine.paintComponent
like this:
Line2D line = new Line2D.Double(0, 0, 1000, 1000);
and you will see the following result:
This line in your original code:
pane.setLayout(null);
is pretty clear - you are using no layout manager, or in other words you chose to use absolute positioning. This means that the coordinates, widths and heights of components must be precalculated and set by you. But if you make a mistake somewhere (as your example nicely shows) it'll be hard to detect. Not to mention, for example if you want to handle window resizing. That's why LayoutManagers exist.
I recommend reading also:
Upvotes: 2
Reputation: 36423
Your main problem is that you use null
/Absolute
layout.
You should have a read here:
1) You should use an appropriate LayoutManager
(or nest together multiple LayoutManager
s) and/or override getPreferredSize()
of JComponent
to return correct dimensions which fit the drawings.
2) Dont call setSize
on JFrame
rather call pack()
before setting JFrame
visible (with above in mind)
3) No need for adding to contentPane via getContentPane().add(..)
as add(..)
setLayout(..)
and remove(..)
have been forwarded to the contentPane.
4) Watch class names, stick to the java convention a class name begins with a capital letter and each new word thereafter the first letter should be capitilized i.e gameContainer
should be GameContainer
, drawingLine
should be DrawingLine
Here is your code with above fixes implemented (not the most well layed out, but its only an example):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class GameContainer {
public static void addComponentsToPane(JFrame frame) {
JPanel buttonPanel=new JPanel();//create panel to hold button
//add button to the pane
JButton b3 = new JButton("B1");
buttonPanel.add(b3);
frame.add(buttonPanel, BorderLayout.EAST);//use contentPane default BorderLayout
//add line to the pane
DrawingLine line1 = new DrawingLine();
frame.add(line1);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up content pane
addComponentsToPane(frame);
//add menu bar
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menu.add(new JMenuItem("Do nothing"));
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
class DrawingLine extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Line2D line = new Line2D.Double(10, 10, 100, 100);
g2d.draw(line);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
Upvotes: 7