java - 将布局管理器与 JPanel 和 Graphics 2D 一起使用
问题描述
我想在 JPanel 上画线等,然后将其添加到 JFrame 并使用.pack()。我的问题是我不知道在那种特殊情况下如何使用布局管理器。通常我使用 gridBagLayout 在面板中添加一个按钮或其他东西,我完全理解这一点。但是对于 2D 图形,我只是直接在面板上绘制。因此我无法正确使用 .pack() 。有人知道如何以正确的方式打包()那个jPanel吗?我的代码如下所示:
public class NetworkViewPanel extends JPanel implements KeyListener, ActionListener {
public NetworkViewPanel(NetworkAI network) {
this.network = network;
this.netList = network.getLayerList();
addKeyListener(this);
setFocusable(true);
this.setLayout(new GridLayout(2, 2, 2, 2)); // does that even make sense ?
}
public void paint(Graphics g) {
super.paint(g);
g2 = (Graphics2D) g;
if (showStandardView) {
drawRectangles();
drawLines();
} else {
drawRectangles();
drawLinesSpecial(listIndex, xIndex);
}
}
问候 :)
解决方案
您可以JPanel
使用布局管理器对 a 进行布局,并在其上进行自定义绘画。
这并不妨碍您使用pack()
1。
以下mre 2JPanel
演示了使用 a 在 a 上绘制一条线GridLayout
:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class NetworkViewPanel extends JPanel{
private final List<JLabel> labels;
public NetworkViewPanel() {
this.setLayout(new GridLayout(2, 2, 2, 2));
this.setPreferredSize(new Dimension(400,300));//used by pack()
labels = new ArrayList<>();
addLabels(new String[]{ "A", "B" , "C" , "D"});
}
private void addLabels(String[] text){
for(String t: text){
JLabel label = new JLabel(t);
label.setBorder(BorderFactory.createLineBorder(Color.BLUE));
label.setHorizontalAlignment(JLabel.CENTER);
add(label);
labels.add(label);
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); //draw panel as layed out by layout manager
drawLines(g);
}
private void drawLines(Graphics g) {
//draw line between centers of first and last components
int x1 = labels.get(0).getBounds().x + labels.get(0).getBounds().width /2;
int y1 = labels.get(0).getBounds().y + labels.get(0).getBounds().height /2;
int x2 = labels.get(labels.size()-1).getBounds().x + labels.get(labels.size()-1).getBounds().width/2;
int y2 = labels.get(labels.size()-1).getBounds().y + labels.get(labels.size()-1).getBounds().height/2;
g.setColor(Color.RED);
g.drawLine(x1, y1, x2, y2);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.add(new NetworkViewPanel());
f.pack();
f.setVisible(true);
}
}
1 请参阅:.pack() 有什么作用?
2 提问或回答时考虑张贴mre
推荐阅读
- angular - 为什么引用`window.location`被认为是一种不好的做法?
- c++ - 如何使用执行?
- azure - Prometheus - 从 Azure VM 内的不同端点抓取指标
- apache-storm - 当我们在 Apache Storm 中运行同一个 spout 的多个实例时,数据如何保持一致
- c# - 如何在 .Net Core 中为 IAntiForgery 接口和 IHttpContextAccessor 创建实例
- python - 从不同数据框中的另一列中查找一个数据框的列中的字符串
- wordpress - 返回 Null 术语自定义分类法 WPGraphQL Headless Wordpress
- python-imaging-library - 使用 Pillow 在 GIF 中的第一帧之后的帧上的黑色背景
- docker - 无法使用 Docker 从 Jenkins 生成魅力报告
- r - 使用正则表达式从字符串中提取元素