Компоненты оказывают необычный способ

java swing graphics

45 просмотра

1 ответ

У меня есть собственный JPanelкласс, и я хочу, чтобы он рисовал несколько прямоугольников и текстов перед его дочерними компонентами. Я переопределил этот метод:

public void paint(Graphics g){
    g = getComponentGraphics(g);
    super.paint(g);
    //paint my custom content
}

super.paintвызывает paintChildrenwhitch рисует дочерние компоненты. Но дочерние компоненты появляются перед моим пользовательским контентом, и они также иногда борются друг с другом.

Я абсолютно не понимаю, что может быть причиной этого.

ПРИМЕЧАНИЕ: я использую setComponentZOrderв своем коде, и мой JPanelпроисходит в JScrollPane.

РЕДАКТИРОВАТЬ: Компоненты ZFight, даже если я никогда не вызываю метод setComponentZOrder.

РЕДАКТИРОВАТЬ 2:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Rectangle;

    import javax.accessibility.Accessible;
    import javax.accessibility.AccessibleSelection;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    public class Example extends JPanel{
        private static final long serialVersionUID = 1L;
        public static void main(String[] atgs){
            JFrame frame = new JFrame("ZFightingExample");
            frame.setSize(new Dimension(500,500));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            ExamplePanel panel = new ExamplePanel();
            frame.add(panel);
            Example a = new Example(new Rectangle(5,5,50,50)),
                    b = new Example(new Rectangle(40,40,50,50));
                    panel.add(a);
            panel.add(b);
            frame.setVisible(true);
        }
        public Example(Rectangle bounds){
            super();
            setBounds(bounds);
        }
        public void paint(Graphics g){
            super.setBackground(Color.GREEN);
            g.fillRect(0, 0, getWidth()-1, getHeight()-1);
            super.paint(g);
            g.setColor(Color.BLACK);
            g.drawRect(0, 0, getWidth()-1, getHeight()-1);
        }
    }
    class ExamplePanel extends JPanel{
        private static final long serialVersionUID = 1L;
        public ExamplePanel(){
            super(null);
            accessibleContext = new Accessiblecontext();
        };
        protected class Accessiblecontext extends AccessibleJPanel implements AccessibleSelection{
            private static final long serialVersionUID = 1L;
            public int getAccessibleSelectionCount() {return 2;}
            public Accessible getAccessibleSelection(int i) {return (Accessible)getComponent(i);}
            public boolean isAccessibleChildSelected(int i) {return true;}
            public void addAccessibleSelection(int i) {}
            public void removeAccessibleSelection(int i) {}
            public void clearAccessibleSelection() {}
            public void selectAllAccessibleSelection() {}
        }
        public void paint(Graphics g){
            super.paint(g);
            g.setColor(Color.BLUE);//Should be in front of the Green boxes...
            g.drawRect(10, 10, 75, 75);
        }
    }
Автор: Gergely Источник Размещён: 08.11.2019 11:21

Ответы (1)


2 плюса

Решение

Я хочу, чтобы он нарисовал несколько прямоугольников и текстов перед дочерними компонентами.

Обычно вы переопределяете paintCompnent (), чтобы выполнить пользовательскую рисование.

Вопрос в том, что для вас значит «впереди»? Если это означает то, что я думаю, значит, вам нужно сделать рисование после того, как дочерние компоненты были нарисованы. Таким образом, ваш базовый подход к переопределению paint () является правильным.

public void paint(Graphics g){
    g = getComponentGraphics(g);
    super.paint(g);
    //paint my custom content
}

Проблема с приведенным выше кодом заключается в том, что вы не используете объект Graphics, переданный в метод рисования. Итак, ваш код должен быть:

public void paint(Graphics g)
{
    //g = getComponentGraphics(g);
    super.paint(g);  // use the Graphics object passed to the method

    //paint my custom content

    g.drawRect(10, 10, 20, 20);
}

Я использую setComponentZOrder в моем коде,

Почему ты играешь с ZOrder?

Редактировать:

g.setColor (Color.BLUE); // Должен быть перед зелеными полями ...

Как я впервые заявил в своем ответе, обычно (в 99% случаев) пользовательское рисование выполняется путем переопределения метода paintComponent () панели.

Проблема с примером класса:

  1. переопределить paintComponent (), а не paint ()
  2. первое утверждение при переопределении метода рисования должно быть супер. ???.
  3. не устанавливайте свойства класса в методе рисования.

Таким образом, код может выглядеть примерно так:

public Example(Rectangle bounds){
    super();
    setBounds(bounds);
    setBackground(Color.GREEN);
}
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(getBackground());
    g.fillRect(0, 0, getWidth()-1, getHeight()-1);
    g.setColor(Color.BLACK);
    g.drawRect(0, 0, getWidth()-1, getHeight()-1);
}

Обратите внимание, что вам не нужно создавать какие-либо пользовательские рисования с помощью класса Example. Вместо этого ваш код может быть что-то вроде:

ExamplePanel panel = new ExamplePanel();
panel.setLayout( null ); // now you set the size/location of any component you add to the panel

JPanel example1 = new JPanel();
example1.setBackground( Color.GREEN );
example1.setBorder( new LineBorder(Color.BLACK) );
example1.setBounds( new Rectangle(....) );

panel.add(example1);

Также другим решением для класса ExamplePanel может быть использование JLayer. Класс JLayer позволяет добавлять все виды художественных оформлений для компонента. Посмотрите учебник Swing о том, как декорировать компоненты с помощью класса JLayer .

Автор: camickr Размещён: 20.08.2016 02:31
Вопросы из категории :
32x32