#java #swing #layout #resize #paintcomponent
#java #качать #макет #изменение размера #paintcomponent
Вопрос:
Моя проблема: у меня есть RoundedPanel
класс, который расширяет JPanel
и переопределяет paintComponent()
метод, чтобы рисовать закругленные углы вокруг панели. Я создал MyPanel
класс, который расширяется RoundedPanel
.
Когда я помещаю панель в MyPanel
использование FlowLayout
layout, появляется закругленная граница. Для того, чтобы компоненты на панели были изменены так, чтобы они занимали максимальное пространство, я заменил FlowLayout
на a Borderlayout
. Но тогда paintComponent()
метод никогда не вызывается, и закругленная граница больше не появляется.
Кто-нибудь знает, как создать округлую панель, компоненты которой растягиваются, чтобы заполнить пространство при изменении размера окна? Может кто-нибудь объяснить мне, почему paintComponent()
метод не вызывается при использовании Borderlayout ?
Заранее спасибо.
Код :
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Demo extends JFrame {
public static final int WINDOW_WIDTH = 540;
public static final int WINDOW_HEIGHT = 540;
private static MyPanel myPanel;
private Demo() {
super();
myPanel = new MyPanel();
getContentPane().add(myPanel);
setSize(new Dimension(500, 500));
setPreferredSize(new Dimension(500, 500));
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
class MyPanel extends RoundedPanel {
private JPanel rootPanel = new JPanel();
public MyPanel() {
super();
rootPanel = buildRootPanel();
rootPanel.setPreferredSize(new Dimension(400, 400));
rootPanel.setBackground(Color.RED);
add(rootPanel);
// When uncommented, the Textfield is correctly resized to fit all available space , but the rounder border doesnt appear
//setLayout(new BorderLayout());
//add(rootPanel, BorderLayout.CENTER);
}
private JPanel buildRootPanel() {
rootPanel.setLayout(new BorderLayout());
JTextField field = new JTextField();
rootPanel.add(field, BorderLayout.CENTER);
return rootPanel;
}
}
class RoundedPanel extends JPanel {
protected int strokeSize = 1;//Stroke size. it is recommended to set it to 1 for better view
private Color strokeColor = Color.BLACK;
protected Color shadowColor = Color.black;//Color of shadow
protected boolean shady = true;// Sets if it drops shadow
protected boolean highQuality = true;// Sets if it has an High Quality view
protected Dimension arcs = new Dimension(20, 20);// Double values for Horizontal and Vertical radius of corner arcs
protected int shadowGap = 5;// Distance between shadow border and opaque panel border
protected int shadowOffset = 4; // The offset of shadow.
protected int shadowAlpha = 150;// The transparency value of shadow. ( 0 - 255)
public RoundedPanel() {
super();
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
System.out.println(" in paintComponent");
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
int shadowGap = this.shadowGap;
Color shadowColorA = new Color(shadowColor.getRed(), shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
Graphics2D graphics = (Graphics2D) g;
//Sets antialiasing if HQ.
if (highQuality) {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
//Draws shadow borders if any.
if (shady) {
graphics.setColor(shadowColorA);
graphics.fillRoundRect(
shadowOffset,// X position
shadowOffset,// Y position
width - strokeSize - shadowOffset, // width
height - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
} else {
shadowGap = 1;
}
//Draws the rounded opaque panel with borders.
graphics.setColor(getBackground());
graphics.fillRoundRect(0, 0, width - shadowGap, height - shadowGap, arcs.width, arcs.height);
//graphics.setColor(getForeground());
graphics.setColor(strokeColor);
graphics.setStroke(new BasicStroke(strokeSize));
graphics.drawRoundRect(0, 0, width - shadowGap, height - shadowGap, arcs.width, arcs.height);
//Sets strokes to default, is better.
graphics.setStroke(new BasicStroke());
}
}
Комментарии:
1. 1 для sscce .
Ответ №1:
Похоже, что поле занимает все пространство панели. Если дочерний элемент покрывает весь родительский элемент, а родительский элемент не виден, нет необходимости вызывать paintComponent(), чтобы он не вызывался. Попробуйте добавить пустую границу к содержимому.
Комментарии:
1. Я попытался добавить пустую границу, но закругленная граница по-прежнему не появляется.
2. @user980340 установка emptyborderработает, обязательно сделайте его достаточно большим, например, 10 во всех направлениях
3. В классе MyPanel я добавил следующую строку : setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); и теперь это работает: появляется закругленная граница, и размеры компонентов изменяются автоматически. Большое спасибо Станиславлю и Клеопатре!