Рисовать линию при нажатии кнопки Swing - PullRequest
0 голосов
/ 23 января 2019

У меня возникли проблемы с рисованием простой линии от Frame до JButton.Проблема возникает только тогда, когда я делаю это с JButton.Если я непосредственно использую JPanel внутри Frame, все в порядке.

JFrame:

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

public class Fenetre extends JFrame {

    public Fenetre(){
        super("Test");
        init();
        pack();
        setSize(200,200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void init() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        JButton button = new JButton("Draw line");

        button.addActionListener((e)->{
            Pane s = new Pane();
            panel.add(s);
            s.repaint();
        });

        panel.setBackground(new Color(149,222,205));

        add(button,BorderLayout.SOUTH);
        add(panel,BorderLayout.CENTER);
    }

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

}

И JPanel с paintComponents():

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

public class Pane extends JPanel {

    public void paintComponents(Graphics g){
        super.paintComponents(g);
        g.drawLine(0,20,100,20);
    }
}

1 Ответ

0 голосов
/ 23 января 2019

Ряд вопросов сразу выскакивают у меня:

  1. Вы должны использовать paintComponent, а не paintComponents (обратите внимание на s в конце), вы слишком высоко в цепочке краски. Также нет необходимости, чтобы какой-либо метод был public, никто за пределами класса не должен вызывать его.
  2. Pane не предоставляет подсказок по размеру, поэтому его размер по умолчанию будет 0x0

Вместо этого это должно выглядеть больше как ...

public class Pane extends JPanel {

    public Dimension getPreferredSize() {
        return new Dimension(100, 40);
    }

    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawLine(0,20,100,20);
    }
}

При добавлении компонентов Swing ленив. Он не запустит макет / прохождение рисования, пока не придет или не попросит. Это оптимизация, поскольку вы можете добавить множество компонентов, прежде чем выполнять этап макета.

Чтобы запросить пропуск макета, вызовите revalidate в обновленном контейнере верхнего уровня. Как правило, если вы звоните revalidate, вам также следует позвонить repaint, чтобы запросить новый проход краски.

public class Fenetre extends JFrame {

    public Fenetre(){
        super("Test");
        init();
        //pack();
        setSize(200,200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void init() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        JButton button = new JButton("Draw line");

        button.addActionListener((e)->{
            Pane s = new Pane();
            panel.add(s);
            panel.revalidate();
            panel.repaint();
            //s.repaint();
        });

        panel.setBackground(new Color(149,222,205));

        add(button,BorderLayout.SOUTH);
        add(panel,BorderLayout.CENTER);
    }

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

}

Это должно, по крайней мере, заставить panel появиться сейчас

...