Проблемы с отображением прозрачности Java Swing

#java #swing #paint

#java #swing #Краски

Вопрос:

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

Я отправил ошибку для приведенного ниже (хотя для утверждения может потребоваться несколько дней): http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7043319

Еще несколько деталей:

  • Он работает с Windows Sun JDK 1.6 версий 13 и 17
  • Сбой в Ubuntu 11.04 x64 как с OpenJDK 1.6.0_22, так и с Sun JDK 1.6.0_24

Что я хочу, так это создать панель фонового изображения с дополнительными панелями поверх нее (с дополнительными компонентами — например, JButtons, пользовательскими фигурами и т.д. — В них) И нарисовать все это правильно. Я использую JLayeredPane для этой цели в своем приложении, но для примера приведенного ниже кода должно быть достаточно. Я открыт для предложений о том, как делать то, что я хочу, независимо от приведенной ниже проблемы.

Я столкнулся с проблемой, что рисование ведет себя действительно странно. Он не перерисовывает полностью (например, только верхнюю часть над изображением), он перерисовывает — из того, что я заметил, все более разнесенными — шагами (например, 1-я краска, 3-я краска, 9-я краска, 21-я краска, 64-я краска и т.д.). Я предполагаю, что я слишком углубляюсь в реализацию здесь — есть ли что-то явно неправильное в приведенном ниже?

Отдельно отметим, что ниже есть три строки с комментариями. Достаточно интересно, что раскомментирование любого из них и комментирование следующей строки решает проблему. Изображения имеют следующие атрибуты (и, похоже, не имеет значения, какое изображение — просто размер):

 cat.jpg       JPEG 640x533 640x533 0 0 8-bit DirectClass  110KB 0.000u 0:00.000
cat-small.jpg JPEG 200x167 200x167 0 0 8-bit DirectClass 7.99KB 0.000u 0:00.000
  

Вот Java-код, с которым у меня возникают проблемы:

 import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class SwingDrawingPrb {
  public static void main(String[] args) throws Exception {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    final JFrame frame = new JFrame("SwingDrawingPrb");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final Container contentPane = frame.getContentPane();

    frame.setLocation(550, 50);
    frame.setSize(1000, 800);
    frame.setVisible(true);

//    ImageIcon image = new ImageIcon(SwingDrawingPrb.class.getResource("/cat-small.jpg"));
    ImageIcon image = new ImageIcon(SwingDrawingPrb.class.getResource("/cat.jpg"));  

    final JPanel imagePanel = new JPanel() {
//      Color trans = new Color(255, 0, 0, 255);
      Color trans = new Color(255, 0, 0, 64);

      protected void paintComponent(Graphics g) {
        System.out.println("painting");
        g.setColor(Color.white);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(trans);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.blue);
        g.drawLine(0, 0, 1000, 1000);
      }
    };
    imagePanel.setBounds(0, 0, image.getIconWidth()   200, image.getIconHeight()   200);
    imagePanel.setLayout(null);

//     JLabel imageLabel = new JLabel("Hello, world!");
    JLabel imageLabel = new JLabel(image);

    imageLabel.setBounds(100, 100, image.getIconWidth(), image.getIconHeight());
    imageLabel.addMouseMotionListener(new MouseAdapter() {
      public void mouseMoved(MouseEvent e) {
        System.out.println("mouseMoved");
        imagePanel.repaint();
      }
    });
    imagePanel.add(imageLabel);

    contentPane.add(imagePanel);
  }
}
  

Ответ №1:

Вам нужно добавить:

 imagePanel.setOpaque(false);
  

Смотрите Фоны с прозрачностью для получения дополнительной информации.

Комментарии:

1. Пробовал это уже на camickr, не работает. На самом деле, перепробовал много вещей, которые не работают 🙂 Как вы видите, я выполняю заполнение цветом. белый, чтобы он не становился все время «темнее» красного. Проблемы в том, что он просто не рисует все. Он рисует часть (почти всегда часть над изображением, но иногда видны другие эффекты). Если у вас есть минутка, попробуйте запустить его — вы поймете, что я имею в виду.

2. Еще одна вещь — иногда (но не всегда — это еще одна вещь, которую я не понимаю), при запуске рамка рисуется правильно — т. Е. изображение кошки над синей линией, идущей на северо-восток над прозрачным красным прямоугольником, как и должно быть. Теперь при любом другом перерисовывании — либо потому, что я вручную вызываю перерисовку при наведении курсора мыши, либо потому, что я изменяю размер окна — оно перерисовывается плохо.

3. Я пропустил, что сначала вы заливаете фон БЕЛЫМ. На самом деле я вообще не замечаю никаких проблем с рисованием. Фон светло-красного цвета с синей диагональной линией, и изображение закрашивается поверх диагональной линии. Я использую JDK6.7 в XP. Возможно, у вас проблема с версией или платформой.

4. Также я должен отметить, что иногда при запуске я просто получаю серый экран. Это потому, что вы делаете фрейм видимым перед добавлением компонентов в фрейм. Метод setVisible (true) должен быть последним вызванным методом.

5. Это может быть так — я на Ubuntu 11.04 с OpenJDK 1.6.0_22 (те же результаты с Sun JDK 1.6.0_24), что может быть так. Я склонен думать, что это операционная система (ну, в любом случае, какой бы уровень ни отвечал за это). Позвольте мне попробовать в Windows.