Я изначально играл с идеей использования JScrollPane
внутри JPopupMenu
с setLightWeightPopupEnabled(false)
. Тем не менее, это появляется в новом окне верхнего уровня над компонентом - поэтому любые закругленные границы рисуются в верхней части окна верхнего уровня. Он выглядит как серый прямоугольник с JScrollPane
, нарисованным сверху с закругленными краями.
Затем я подумал о том, чтобы поместить ScrollPane
в Panel
, который мог бы справиться с рисованием округленной границы вокруг него. К сожалению, у компонентов AWT нет свойства setOpaque()
, как у компонентов Swing, поэтому они имеют прямоугольную форму. Я мог бы скопировать тот же цвет фона, что и родительский, но если бы вы хотели отобразить это поверх некоторых данных, это было бы довольно очевидно.
Компромиссный подход, который я наконец-то нашел, заключался в том, чтобы компонент Container
нарисовал границу вокруг дочернего элемента ScrollPane
. Это определенно скорее хакерское решение, но пока единственное, что сработало ... вот окончательный код:
package stackoverflow;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.List;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.ScrollPane;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class CanvasPopup {
public static void main(String[] args) {
final Frame f = new Frame("CanvasPopup");
final ScrollPane scroll = new ScrollPane();
final Panel c = new Panel(null) {
@Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, getWidth(), getHeight());
if (scroll.isVisible()) {
g.setColor(Color.RED);
Rectangle bounds = scroll.getBounds();
g.fillRoundRect(bounds.x - 10, bounds.y - 10,
bounds.width + 20, bounds.height + 20, 15, 15);
}
}
};
final List list = new List();
for (int i = 0; i<100; i++) {
list.add("Item " + i);
}
scroll.add(list);
scroll.setBounds(75, 75, 150, 150);
scroll.setVisible(false);
c.add(scroll);
c.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!scroll.isVisible()) {
scroll.setLocation(e.getPoint());
}
scroll.setVisible(!scroll.isVisible());
c.repaint();
}
});
f.add(c);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setSize(300, 300);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}