1

I need help here. I want to give a parameter to the drawLine() method which I get from getSize(). I want to draw a line throughout the whole window by using the getSize() method.

package PROG2;

import java.awt.*;
import javax.swing.*;

class MyComponent extends JComponent {

    @Override
    public void paintComponent(Graphics g) {
        g.drawLine(100, 100, 200, 200);
    }
}
    
public class Übung1 extends JFrame{

    public static void berechnen() {
        int height = frame.getHeight(); //Here it says it doesn't know "frame" variable but I don't know how to declare it here.
        int width = frame.getWidth();
    }

    public static void main(String[] args){
            JFrame frame = new JFrame("First window");
            berechnen();
            frame.add(new MyComponent());
            frame.setSize(400, 400);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            Graphics g = frame.getGraphics();

            // int width = frame.getWidth();
            // int height = frame.getHeight();
            System.out.println("Größe:" + frame.getSize());
            //System.out.println(width);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Bunsekanse
  • 25
  • 6
  • 1
    Don't worry about the frame height & width, it is the width & height of `MyComponent` that matters. The `getSize()` method of that can be called within the `paintComponent` method - right where & when the info is needed. **P.S:** when custom painting, first call the `super` method of the paint method. – Andrew Thompson Apr 30 '22 at 15:05
  • 1
    I second what @AndrewThompson mentioned above and also will state that you were correct to comment-out the `while (true)` block as this has no place in an event-driven Swing GUI. – Hovercraft Full Of Eels Apr 30 '22 at 15:09
  • 2
    And also, I urge you not to get a Graphics object via `frame.getGraphics();` call on the JFrame or on any component as this will return a short-lived, unstable and potentially null reference. – Hovercraft Full Of Eels Apr 30 '22 at 15:10
  • 1
    Other issues with regard to the `berechnen()` method: 1) No idea why you're using a static method. 2) The height and width variables within that method are local, will disappear once the method ends and are thus of no use to you or your program. 3) The method tries to use a variable that simply doesn't exist within that scope. Where do you declare a frame variable anywhere except within the main method, and per Java scoping rules, that variable is only visible within that same main method and nowhere else. – Hovercraft Full Of Eels Apr 30 '22 at 15:15
  • But how do I use the parameter I get from getSize() method to draw a line throughout the component? – Bunsekanse Apr 30 '22 at 15:23
  • I am very new to Java and JFrame, Graphics 'n stuff so I please you to be very detailed and well explained :) Thank you – Bunsekanse Apr 30 '22 at 15:24
  • Additionally if I call the getSize() method I get a Dimension value, not an integer which I cant use in the drawLine() method. – Bunsekanse Apr 30 '22 at 15:32
  • 1
    *"Additionally if I call the getSize() method I get a Dimension value, not an integer which I cant use in the drawLine() method."* -- learn to use the API, and read the [Dimension API entry](https://docs.oracle.com/en/java/javase/14/docs/api/java.desktop/java/awt/Dimension.html). Note that this object has a width and height field that *can* be used where needed. – Hovercraft Full Of Eels Apr 30 '22 at 15:50
  • @HovercraftFullOfEels *"Learn to use the API"* +10,000 to that! – Andrew Thompson Apr 30 '22 at 16:07

1 Answers1

1

As Andrew already stated,

  • you don't want to get the dimensions or size of the JFrame but rather the component that is being displayed within the JFrame's contentPane, here your MyComponent instance.
  • The best place to get that information is inside of the paintComponent method itself, just prior to drawing the line.
  • And always call the super's painting method first

I also recommend:

  • Draw within a JPanel's paintComponent method, not a JComponent, if you want an opaque image
  • Avoid static methods and fields unless absolutely needed

Note that in the code below, the red line draws through the JPanel's diagonal, and continues to draw the diagonal, even when the JFrame is manually resized:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;

import javax.swing.*;

public class DrawLine extends JPanel {
    private static final Stroke LINE_STROKE = new BasicStroke(15f);
    private static final Dimension PREF_SIZE = new Dimension(800, 650);

    public DrawLine() {
        setPreferredSize(PREF_SIZE);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        // code to make the line smooth (antialias the line to remove jaggies)
        // and to make the line thick, using a wider "stroke"
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setStroke(LINE_STROKE);

        // if we want a red line
        g2.setColor(Color.RED);

        // this is the key code here:
        int width = getWidth();
        int height = getHeight();
        
        // draw along the main diagonal:
        g2.drawLine(0, 0, width, height);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            DrawLine mainPanel = new DrawLine();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Hi, first of all thank you so much. That REALLY helps me to get into the topic. Second, why do I need to call the super paint method? – Bunsekanse Apr 30 '22 at 16:36
  • @Bunsekanse: the super method does the house-keeping painting that the paintComponent method is responsible for. If you don't call it, you break the painting "chain", the house-keeping painting does not occur and dirty pixels can persist. – Hovercraft Full Of Eels Apr 30 '22 at 16:41
  • @Bunsekanse: Please see [What does super.paintComponent(g) do?](https://stackoverflow.com/questions/28724609/what-does-super-paintcomponentg-do) as well as 1) [Lesson: Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html), an introductory tutorial to Swing graphics. 2) [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html), an advanced tutorial on Swing graphics. – Hovercraft Full Of Eels Apr 30 '22 at 16:41