Java JFrame tegner ikke linjer i vinduet

Indlæg af Hanne Mølgaard Plasc

Problem



package Main;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;

public class Main extends JFrame{

    public static void main(String[] args) {

        int width = 800;
        int height = 600;
        String title = "Test";

        JFrame display = new JFrame();
        display.setTitle(title);
        display.setSize(width, height);
        display.setVisible(true);
        display.setDefaultCloseOperation(JFrame.EXIT\_ON\_CLOSE);
    }

    public void paint(Graphics g) {

        g.setColor(Color.white);
        g.drawLine(0, 100, 800, 300);

        getContentPane().setBackground(Color.black);
    }

}


Jeg bruger Java's JFrame. Så det erkender ikke malingsmetoden og kan ikke finde ud af hvorfor. Jeg har set på YouTube-videoer og ser et kig på at se om nogen har haft lignende problemer, men alt jeg har fundet synes ikke at hjælpe problemet .


når jeg sætter baggrundsfarven i hoveddelen, fungerer den, lidt i maling, det synes ikke at gøre noget og efterlader det blankt.


Dens en hvid linje over en sort baggrund, så jeg burde let kunne se den.

Bedste reference


Du opretter en forekomst af JFrame med


JFrame display = new JFrame();


Men klassen JFrame har ingen logik til at tegne en hvid linje på en sort baggrund. Den logik er i din brugerdefinerede klasse Main. Så i stedet skal du oprette en forekomst af Main:


JFrame display = new Main();


Imidlertid ændrer den stadig ikke problemet, fordi du indstiller baggrundsfarven på indholdsruden, men forsøger at tegne direkte på selve JFrame. Den foretrukne løsning her er at udvide JPanel]] i stedet for JFrame og tilsidesætte sin paintComponent() metode. Derefter opret en forekomst af din nye klasse til at bruge som indholds smerte:


import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainPanel extends JPanel{

    public static void main(String[] args) {

        int width = 800;
        int height = 600;
        String title = "Test";

        JFrame display = new JFrame();
        display.setTitle(title);
        display.setSize(width, height);
        display.setVisible(true);
        display.setDefaultCloseOperation(JFrame.EXIT\_ON\_CLOSE);

        display.setContentPane(new MainPanel());
    }

    public MainPanel() {
        setBackground(Color.black);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.white);
        g.drawLine(0, 100, 800, 300);
    }
}


Bemærkninger:



  1. Jeg kalder setBackground() i konstruktøren, fordi den ikke er afhængig af Graphics eksemplet, der er overført til paintComponent(). Dette undgår også overhead af et andet funktionsopkald for hver render.

  2. I paintComponent() kalder jeg super.panitComponent(). Dette gør det muligt for JPanel at rydde det område, der skal males, og enhver anden nødvendig initialisering.


Andre referencer 1


Selvfølgelig ved jeg ikke meget om Swing (jeg foretrækker JavaFX). Det er dog klart, at din hovedklasse er en JFrame, så du bør ikke lave en ny indenfor den. Alle de metoder du kalder på display er bygget i din nuværende klasse. Dybest set har du i JFrame lavet en ny JFrame. Din paint metode blev imidlertid kaldt på forælder JFrame, som du aldrig har synliggjort. Dette løser dit problem (du skal muligvis fuldskærm vinduet):


import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;

public class Main extends JFrame{

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        int width = 800;
        int height = 600;
        String title = "Test";

        setTitle(title);
        setSize(width, height);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT\_ON\_CLOSE);
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.WHITE);
        g.drawLine(100, 100, 800, 300);

        getContentPane().setBackground(Color.black);
    }

}