2016-11-10 17 views
0

Я ищу способ рисовать несколько JComponents друг над другом (перекрываются) и по-прежнему могут индивидуально обращаться и изменять их.Как создать независимые JPanel-слои в JFrame и перекрасить каждый отдельно

E.g. краска три JPanels с прозрачным фоном - каждый из которых содержит круг, прямоугольник или линию. Впоследствии я хотел бы изменить внешний вид круга. Остальные два не следует перекрашивать (аналогично слоям в Photoshop).

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

Есть ли достойный способ достичь этого? Спасибо вам за ваши идеи!

+0

Лучшим способом было бы иметь один JPanel и несколько BufferedImages в качестве ваших слоев. Покрасьте каждый BufferedImage в порядок, стараясь не рисовать прозрачные области. Вам нужно очистить и перекрасить всю область рисования для каждого кадра анимации. Кроме того, ваш рисунок paintComponent метод рисования должен просто рисовать. Нет расчетов. Ничего другого, кроме методов Graphics2D. Конечной альтернативой было бы моделирование ваших геометрических фигур и рисование фигур из модели. –

+0

Взгляните на мои [Moving Eyes] (http://stackoverflow.com/questions/34981403/bufferedimage-not-being-cleared-before-each-rendering/35002727#35002727) ответьте, чтобы посмотреть, как настроить чертеж панель в Swing. –

+0

Похоже, что это могло решить мою проблему! BufferedImages как слои - я попробую! Спасибо! –

ответ

0

мне нужно изменить прямоугольник на заднем

Вы можете вызвать:

panel.repaint(rectangle); // or 
panel.repaint(x, y, width, height); 

указать Прямоугольная область, которая будет перекрашен.

+0

Благодарим вас за быстрый ответ. Но в моем сценарии все jpanels лежат прямо друг над другом, поэтому у них одинаковые ограничивающие прямоугольники. То есть перекрашивание прямоугольника приводит к перекрашиванию всех остальных слоев. В принципе, прямоугольник эквивалентен фону. –

+0

Это правильно. Swing будет смотреть на компонент, который вы хотите перекрасить, и посмотреть на всех его родителей, пока он не найдет компонент с непрозрачным фоном. Затем он рисует фон и все дочерние компоненты в этом месте. Это делается для того, чтобы поверхность была полностью окрашена без артефактов. Мое предложение заключалось в том, чтобы не нарисовать прямоугольник всей панели, а только подмножество панели, которая изменилась. Поэтому, когда вы меняете круг, вы перекраиваете область, полностью содержащуюся в круге. – camickr

+0

@MatthiasK, перекрашивание панелей, содержащих круг прямоугольник и линию, не является проблемой. Я нарисовал сотни объектов одновременно без проблем. У вас должна быть другая проблема с картинкой. – camickr

0

Это сработало довольно хорошо - вот мой код, если у кого-то есть аналогичная проблема! первое изображение может быть сохранено и отображено позже (buff) Обязательно создайте новый BufferedImage (здесь холст) при повторном отображении, так как трансверсация потеряна иначе. Благодаря Gilbert Le Blanc

@Override 
protected void paintComponent(Graphics g1) { 
    //Create image: 
    BufferedImage buff = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_INT_ARGB); 

    //write to image: 
    Graphics2D g2 = (Graphics2D) buff.getGraphics(); 
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,(float) 0.01f)); 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    g2.draw(xxxRectanglewhatever); 

    //then - later draw image again 
    BufferedImage canvas = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_INT_ARGB); 
    canvas.getGraphics().drawImage(buff, 0, 0, null); 
    ((Graphics2D) g1).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); 
    g1.drawImage(canvas, 0, 0, null); 
    canvas.flush(); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^