Как установить прозрачный фон JPanel?
Может ли JPanel
фон быть прозрачным?
Мой кадр имеет два JPanel
s:
- Панель изображений и
- Панель функций.
Панель функций перекрывает панель изображений.
Панель изображений работает в качестве фона и загружает изображение с удаленного URL-адреса.
В панели функций я хочу рисовать фигуры. Теперь панель изображений не может быть видна из-за цвета фона Feature Panel.
Мне нужно сделать прозрачность панели функций прозрачной, все еще рисуя ее фигуры, и я хочу, чтобы панель изображений была видимой (поскольку она выполняет функцию разбиения и кеширования изображений).
Я использую два JPanel
, потому что мне нужно отделить рисунок изображения и фигуры.
Есть ли способ, которым перекрывающий Jpanel имеет прозрачный фон?
Ответы
Ответ 1
В качестве альтернативы рассмотрите Стеклянная панель, обсуждаемая в статье Как использовать корневые панели. Вы можете нарисовать свой контент "Feature" в стеке paintComponent()
.
Приложение: работая с GlassPaneDemo, я добавил изображение:
/* Set up the content pane, where the "main GUI" lives. */
frame.add(changeButton, BorderLayout.SOUTH);
frame.add(new JLabel(new ImageIcon("img.jpg")), BorderLayout.CENTER);
и изменил метод стекла paintComponent()
:
protected void paintComponent(Graphics g) {
if (point != null) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.3f));
g2d.setColor(Color.yellow);
g2d.fillOval(point.x, point.y, 120, 60);
}
}
изображение http://i41.tinypic.com/2j0mlv9.png
Ответ 2
Вызов setOpaque(false)
в верхнем JPanel
должен работать.
Из вашего комментария, похоже, что картина Swing может быть сломана где-то -
Сначала вы, вероятно, захотите переопределить paintComponent()
, а не paint()
в любом компоненте, который у вас есть paint()
, переопределенном.
Вторые - когда вы переопределяете paintComponent()
, сначала сначала нужно вызвать super.paintComponent()
, чтобы сделать все рисовальные материалы по умолчанию Swing (из которых честь setOpaque()
- одна).
Пример -
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TwoPanels {
public static void main(String[] args) {
JPanel p = new JPanel();
// setting layout to null so we can make panels overlap
p.setLayout(null);
CirclePanel topPanel = new CirclePanel();
// drawing should be in blue
topPanel.setForeground(Color.blue);
// background should be black, except it not opaque, so
// background will not be drawn
topPanel.setBackground(Color.black);
// set opaque to false - background not drawn
topPanel.setOpaque(false);
topPanel.setBounds(50, 50, 100, 100);
// add topPanel - components paint in order added,
// so add topPanel first
p.add(topPanel);
CirclePanel bottomPanel = new CirclePanel();
// drawing in green
bottomPanel.setForeground(Color.green);
// background in cyan
bottomPanel.setBackground(Color.cyan);
// and it will show this time, because opaque is true
bottomPanel.setOpaque(true);
bottomPanel.setBounds(30, 30, 100, 100);
// add bottomPanel last...
p.add(bottomPanel);
// frame handling code...
JFrame f = new JFrame("Two Panels");
f.setContentPane(p);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(300, 300);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
// Panel with a circle drawn on it.
private static class CirclePanel extends JPanel {
// This is Swing, so override paint*Component* - not paint
protected void paintComponent(Graphics g) {
// call super.paintComponent to get default Swing
// painting behavior (opaque honored, etc.)
super.paintComponent(g);
int x = 10;
int y = 10;
int width = getWidth() - 20;
int height = getHeight() - 20;
g.drawArc(x, y, width, height, 0, 360);
}
}
}
Ответ 3
В моем конкретном случае было легче сделать это:
panel.setOpaque(true);
panel.setBackground(new Color(0,0,0,0,)): // any color with alpha 0 (in this case the color is black
Ответ 4
(Feature Panel).setOpaque(false);
Надеюсь, что это поможет.
Ответ 5
public void paintComponent (Graphics g)
{
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.0f)); // draw transparent background
super.paintComponent(g);
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f)); // turn on opacity
g.setColor(Color.RED);
g.fillRect(20, 20, 500, 300);
}
Я попытался сделать это таким образом, но это очень проблематично
Ответ 6
Как Thrasgod правильно показал в своем ответе, лучший способ - использовать paintComponent, но также, если дело в том, чтобы иметь полупрозрачный JPanel (или любой другой компонент, действительно) и иметь что-то непрозрачное внутри. Вы также должны переопределить метод paintChildren и установить значение alfa равным 1.
В моем случае я расширил JPanel следующим образом:
public class TransparentJPanel extends JPanel {
private float panelAlfa;
private float childrenAlfa;
public TransparentJPanel(float panelAlfa, float childrenAlfa) {
this.panelAlfa = panelAlfa;
this.childrenAlfa = childrenAlfa;
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(getBackground());
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, panelAlfa));
super.paintComponent(g2d);
}
@Override
protected void paintChildren(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(getBackground());
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_ATOP, childrenAlfa));
super.paintChildren(g);
}
//getter and setter
}
И в моем проекте мне нужно всего лишь создать экземпляр Jpanel jp = new TransparentJPanel(0.3f, 1.0f);
, если я хочу только прозрачность Jpanel.
Вы могли бы также испортить форму JPanel с помощью g2d.fillRoundRect
и g2d.drawRoundRect
, но это не входит в объем этого вопроса.