I am extending the JButton function so as to automate a couple of things, so I have only added this function:
public void addButton(Container container, int left, int top, int width, int height)
{
this.setBounds(left, top, width, height);
this.setSize(width, height);
container.add(this);
this.repaint();
}
and I am running this code in my pannel:
buttonLeft = new extendedButton("Left");
buttonMiddle = new extendedButton("Middle");
buttonRight = new extendedButton("Right");
Insets inset = this.getInsets();
setLayout(null);
Container c = getContentPane();
buttonLeft.addButton(c, inset.left, inset.top, 150, 50);
buttonMiddle.addButton(c, inset.left + buttonLeft.WIDTH, inset.top, 150, 50);
buttonRight.addButton(c, inset.left + buttonLeft.WIDTH + buttonRight.WIDTH, inset.top, 150, 50);
however, though I expect the buttons to appear one next to the other, they seem to appear one on top of the other and one pixel to the right. If however I replace the .WIDTH parameter with 150, it works as expected, any clues as to why .WIDTH denies to give the value I have set?
I am not using a layout, I gave it null as a parameter.
Related
I'm trying to draw vertical lines to separate days in a week on a JFrame. The code seems fine as no error but when I run it, it output a frame like the picture below. Am I missing anything?
public class WeekToView extends JFrame{
public WeekToView(){
setTitle("Sheffield Dental Care"); //set title
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenDimensions = toolkit.getScreenSize();
setLocation(new Point(screenDimensions.width*1/4, screenDimensions.height*1/4)); //set location based on screen size
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
getContentPane().add(scrPane);
double size[][] = {{150, 150, 150, 150, 150}, // Columns
{100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}}; // Rows
container.setLayout(new TableLayout(size));
String daysInWeek[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
JLabel daysInWeekLabels[] = new JLabel[daysInWeek.length];
for (int i = 0; i < daysInWeek.length; i++) {
daysInWeekLabels[i] = new JLabel(daysInWeek[i],SwingConstants.CENTER);
}
container.add(daysInWeekLabels[0], "0,0");
container.add(daysInWeekLabels[1], "1,0");
container.add(daysInWeekLabels[2], "2,0");
container.add(daysInWeekLabels[3], "3,0");
container.add(daysInWeekLabels[4], "4,0");
setSize(780,600); //set size based on screen size
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false); //unresizable
setVisible(true);
}
public void paintComponent(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawLine(getWidth()/5,0,getWidth()/5,getHeight());
g2.drawLine(getWidth()*2/5,0,getWidth()*2/5,getHeight());
g2.drawLine(getWidth()*3/5,0,getWidth()*3/5,getHeight());
g2.drawLine(getWidth()*4/5,0,getWidth()*5/5,getHeight());
}
}
There is no paintComponent() method in a JFrame. Whenever you attempt to override a method you should always use #Override before the method name. You will get a compile error if you don't override the method correctly.
You could override paint() but in general don't try to do custom painting in the paint() method of a JFrame.
Instead custom painting is done by overriding the paintComponent() method of the panel that you add to the frame.
Better yet you can use a JTable, which already provides you with a row/column based component.
I want to get the exact height of my string in pixels on my panel. So I wrote a program that draws the string, and then draws a rectangle around it.
Using FontMetrics I used the getStringBounds method to get me the enclosing rectangle.
However it looks wrong :
I was expecting the rectangle to perfectly enclose my text, but there is space at the top (And a tiny bit of space on the left and right). Why is it giving me this result?
Here is my code :
public class Test extends JPanel {
#Override
protected void paintComponent(Graphics g) {
Font font = new Font("Arial", Font.PLAIN, 60);
g.setFont(font);
FontMetrics fm = this.getFontMetrics(font);
String str = "100dhgt";
Rectangle2D rect = fm.getStringBounds(str, g);
int x = 5;
int y = 100;
g.drawRect(x, y - (int)rect.getHeight(), (int)rect.getWidth(), (int)rect.getHeight());
g.drawString(str, x, y);
}
public static void main(String[] args) {
JFrame f = new JFrame();
Test test = new Test();
f.add(test);
f.setVisible(true);
f.setSize(400, 400);
}
}
Regarding your rectangle, you have to consider the font's descend (how far is it below the line)
g.drawString(str, x, y - fm.getDescent());
Also note that the font height usually considers some kind of line spacing. In this case fm.getDescent() + fm.getAscent() = 68 whereas fm.getHeight() = 70
The space at the top can be explained by your not taking account of the descent (which takes me back to one of my favorite methods from java 1.0: getMaxDecent)
Otherwise, the box looks pretty good. The only other advice I can offer is that fm.getStringBounds works better with some fonts than it does with others
So I have this class inside a class which is an implementation of JPanel.
private static class Line extends JComponent {
private static final long serialVersionUID = 1L;
#Override
public void paintComponent(Graphics g) {
System.out.println("Pozvan paintComponent()");
g.setColor(Color.YELLOW);
g.drawLine(20, 20, 100, 20);
super.paintComponent(g);
}
}
This is a snippet of code which creates a single instance of Line:
Line line = new Line();
line.setOpaque(true);
add(line);
I really don't know what I am doing wrong here. When I draw a rectangle, everything is nicely drawn.
when I set the height to remotely big number it works.
The default size of a Swing component is (0, 0). Since the size is 0, there is nothing to paint.
g.drawLine(20, 20, 100, 20);
Using the above information this means your component needs a size of (120, 40). That is, width = 20 + 100 and height = 20 + 20, in order for the component to be painted.
I added line.setBounds(20, 20, 80, 50);
Only part of your line will be painted, since you set the width to 80, not 120.
Read the section from the Swing tutorial on Custom Painting for more information and examples.
I am trying to learn Swing and have made a panel (with help from other StackOverflow code). I added a checkerboard design on a frame, but I have found that the frame is not as big as it should be.
Here is my code:
#Override
protected void paintComponent(Graphics g) {
int width = getWidth(), height = getHeight();
g.clearRect(0, 0, width, height);
g.setColor(Color.BLACK);
for (int i=0;i<=width;i+=50) {
g.drawLine(0,i,width,i);
}
for (int i=0;i<=height;i+=50) {
g.drawLine(i,0,i,height);
}
label.setText("H = "+ getHeight() +" W = "+ getWidth()); // check actual size
add(label);
}
private void gui(Pan window) {
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
frame.setSize(400, 400); // size written here
frame.setVisible(true);
}
If you run it, you'll see the size of the window. It will be 362 by 384, instead of 400 by 400 as written in the code.
If I change the dimensions to 500 by 500, the window will be 462 by 484.
Q: Why are the dimensions off by 38 and 16?
It will be 362 by 384, instead of 400 by 400
Because the size of the frame include the title bar and borders. Don't use the setSize() method.
Instead override the getPreferredSize() method of your custom panel to return the size that you want the panel to be.
Then you use:
frame.pack();
Then the size of the frame will be the preferred size of your panel, plus the size of the title bar and borders.
I am creating an app that uses an undecorated border and wanted to add a shadow to the my JFrame. I got the shadow working but in the process the text got all screwed up.
Due to the size of the program I can not post all of my code but the problem does go away when I remove this line.
setBackground(new Color(0, 0, 0, 0));
So what could cause the text to display blurry and incorrectly? It is bolder and some of the letters seem to be taller.
And I cannot post a picture since I do not have a level 10 reputation.
Here is more of my code:
int extendBy=30;
setMaximumSize(new Dimension(width + extendBy, height + extendBy));
setMinimumSize(new Dimension(width + extendBy, height + extendBy));
setPreferredSize(new Dimension(width + extendBy, height + extendBy));
setUndecorated(true);
setBackground(new Color(0, 0, 0, 0)); // all hell breaks loose here
setContentPane(new ShadowPane());
getContentPane().setBackground(Color.BLACK);
setLocationRelativeTo(null);
setLayout(null); // I know setting null this is bad practice
edit: acquired 10 reputation so here is a pic (look at W or A or k):
Try to override the paintComponent method for this JTable.
How to do it: Overriding paintComponent
For Your case i would use anti-aliasing to get rid of those unwanted effects.
jTable1 = new javax.swing.JTable(){
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON );
}
};