Java Swing: круглые значки видны только в мигающем красном состоянии.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Java Swing: круглые значки видны только в мигающем красном состоянии.

Сообщение Anonymous »

Я борюсь с проблемой рендеринга в моем приложении Java Swing. У меня есть собственный класс JPanel, представляющий источники света, которые должны отображаться в виде кругов. Эти индикаторы размещаются поверх серверных панелей, которые также являются пользовательскими компонентами JPanel со скругленным прямоугольным фоном.
Проблема в том, что эти круглые индикаторы видны только тогда, когда они активно мигает красным (состояние, контролируемое таймером). В зеленом состоянии по умолчанию, а также в неактивном или аварийном состоянии они вообще не отображаются.
Основные сведения:
  • Я использую метод PaintComponent в пользовательском классе JPanel как для источников света, так и для серверных панелей.
  • Я установил setOpaque(false) на источниках света, чтобы включить фон серверных панелей чтобы их было видно.
  • Огни добавляются на главную панель после панелей сервера.
I подозреваю, что проблема связана с тем, как в моем коде обрабатывается прозрачность или порядок отрисовки.
Фрагменты кода: Класс: PaintComponent Метод

Код: Выделить всё

@Override
protected void paintComponent(Graphics g) {
int diameter = Math.min(getWidth(), getHeight());
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

switch (lightState) {
case GREEN:
g2d.setColor(Color.GREEN);
break;
case RED:
g2d.setColor(Color.RED);
break;
case CRASHED:
g2d.setColor(Color.BLACK);
break;
case INACTIVE:
g2d.setColor(Color.GRAY);
break;
}

g2d.fillOval((getWidth() - diameter) / 2, (getHeight() - diameter) / 2, diameter, diameter);
g2d.dispose();

timerLabel.setForeground(Color.WHITE);
timerLabel.setVisible(lightState == LightState.RED);
}

Код: Выделить всё

ServerPanel
: метод PaintComponent

Код: Выделить всё

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(SERVER_BACKGROUND_COLOUR);
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20);
g2d.dispose();
}
Настройка графического интерфейса

Код: Выделить всё

for (Server server : servers) {
JPanel serverBackground = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(SERVER_BACKGROUND_COLOUR);
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20);
g2d.dispose();
}
};
serverBackground.setOpaque(false);
serverBackground.setBounds(server.getX(), server.getY(), SERVER_WIDTH, SERVER_HEIGHT);
serverBackground.setBorder(BorderFactory.createLineBorder(Color.BLACK, 4)); // Thicker border

mainPanel.add(serverBackground);

int lightY = server.getY() + ((SERVER_HEIGHT - (NUM_LIGHTS_PER_SERVER * LIGHT_HEIGHT)) / (NUM_LIGHTS_PER_SERVER + 1));
for (Light light : server.getLights()) {
light.setBounds(server.getX() + (SERVER_WIDTH - LIGHT_WIDTH) / 2, lightY, LIGHT_WIDTH, LIGHT_HEIGHT);
mainPanel.add(light);
lightY += LIGHT_HEIGHT + ((SERVER_HEIGHT - (NUM_LIGHTS_PER_SERVER * LIGHT_HEIGHT)) / (NUM_LIGHTS_PER_SERVER + 1));
}
}
Инициализация индикаторов

Код: Выделить всё

for (int i = 0; i < NUM_LIGHTS_PER_SERVER; i++) {
lights.add(new Light(game));
}
Наблюдения:
  • Огни видны только тогда, когда их состояние освещения имеет значение RED.
  • Зеленое, неактивное и аварийное состояние ничего не отображает.
  • Удаление super.paintComponent() или неправильная настройка прозрачности могли способствовать этому. к этому вопросу.
Попытки отладки:
  • Проверено, что PaintComponent всегда рисует круг.
  • Используется setOpaque(false) для обработки прозрачности.
  • Проверил разные порядки отрисовки компонентов.
  • Проверил, что fillOval() вызывается с правильными параметрами.
  • Убедились, что видимость и передний план timerLabel настроены правильно.
Вопрос:
Почему мои индикаторы видны только тогда, когда они активно мигают красным, и как я могу сделать их всегда видимыми во всех состояниях (зеленый, неактивный, сбой и мигающий красный), когда поверх них отображается метка таймера?
Любые указания или предложения чтобы решить эту проблему, мы будем очень признательны! Спасибо!
РЕДАКТИРОВАТЬ: Вот несколько скриншотов для контекста. Первый — это то, что мне нужно, только с кругами вместо квадратов. Второй — текущий выход — он остается таким до тех пор, пока система не обнаружит сбой (не вовремя щелкнув индикатор), однако индикатор не появляется ни на каком этапе выполнения.
Изображение 1: текущий выходИзображение 2: желаемый результат, но с квадратами вместо кругов

Подробнее здесь: https://stackoverflow.com/questions/793 ... -red-state
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»