Как сделать легкий компонент Swing или AWT полупрозрачным в Java - PullRequest
0 голосов
/ 15 декабря 2011

Некоторое время назад я пытался реализовать метод полупрозрачности для компонентов Swing / AWT, и только сейчас попробовал его впервые.Тем не менее, несколько сбоев в пользовательском интерфейсе появляются при реализации.Код метода приведен ниже:

  public static void setTransparency(Component comp, float t)
  {
    try
    {
      if (comp instanceof Window)
      {
        try
        {
//For JDK 1.7
          ((Window) comp).setOpacity(t);
        }
        catch (Throwable th)
        {
          System.err.println("JRE may be less than 1.7!");
          if (!th.getClass().isInstance(new NoSuchMethodError()))
            th.printStackTrace();
          try
          {
//For JDK 1.6
            com.sun.awt.AWTUtilities.setWindowOpacity((Window) comp, t);
          }
          catch (Throwable th1)
          {
            throw new UnsupportedOperationException("It seems that transparency is not supported", th1);
          }
        }
      }
      else
      {
        if (comp instanceof JComponent)
          ((JComponent)comp).setOpaque(false);
        Graphics2D g2 = (Graphics2D) comp.getGraphics().create();
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, t));
        comp.paint(g2);
        g2.dispose();
      }
    }
    catch (Throwable th)
    {
      throw new UnsupportedOperationException("Transparency might not be supported", th);
    }
  }

При запуске компонент не изменяется по внешнему виду. Есть ли у кого-нибудь предложение о том, чтобы сделать полупрозрачный компонент Swing или AWT таким, чтобы он был на 100% надежным? Это относится только к легким компонентам, так как прозрачные материалы большой плотности покрываются отдельно и на 100% надежны, как показано выше.

Ответы [ 2 ]

1 голос
/ 16 декабря 2011

Ах, вы можете захотеть взглянуть на JLayer (или JXLayer для См. Учебник

0 голосов
/ 16 декабря 2011

Ну, вот ваша первая проблема:

Graphics2D g2 = (Graphics2D) comp.getGraphics().create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, t));
comp.paint(g2);
g2.dispose();

Вы должны рисовать компоненты только внутри вызова paint(Graphics g). Рисование во время вызова вашего setTransparency метода - плохая идея, потому что оно будет стерто в следующий раз, когда Swing решит вызвать paint. Вам нужно, чтобы ваш компонент обрабатывал свою собственную прозрачность в методе paintComponent.

Также это: if (!th.getClass().isInstance(new NoSuchMethodError()))

Что на земле ты делаешь? Что не так с простым catch (NoSuchMethodError e)? Или, если вы действительно хотите использовать instanceof, тогда th instanceof NoSuchMethodError?

Кстати, @WalterLaan и @JimN знают, о чем они говорят. setOpaque (или, точнее, isOpaque) - это подсказка рендеринга движку Swing, которая может помочь ему оптимизировать его работу. Проверьте Javadocs, и вы поймете, что я имею в виду. Это не имеет ничего общего с включением или выключением фона. Ну, это не полностью true - JComponent, по умолчанию, выполняет некоторую хитрость со свойством opaque, чтобы автоматически рисовать фон, если это уместно, но если вы обрабатываете свою собственную картину, тогда эта хитрость будет вероятно, будет отменено.

РЕДАКТИРОВАТЬ: Относительно ошибки NoSuchMethodError. Посмотрите на это:

void setTransparency(Window w, double t) {
    try {
        setOpacity17(w, t);
        return;
    }
    catch (NoSuchMethodError e) {
        System.err.println("JRE *is* less than 1.7!"); // We know the JRE must be < 1.7 because the right methods are known to exist in 1.7.
    }
    catch (Throwable t) {
        t.printStackTrace();
    }
    try {
        setOpacity16(w, t);
    }
    catch (Throwable t) {
        System.err.println("Boom!");
    }
}

void setOpacity17(Window w, double t) {
    ...
}

void setOpacity16(Window w, double t) {
    ...
}

Это намного чище. Обратите внимание на return, который закоротит функцию в случае успеха версии 1.7.

...