gpt4 book ai didi

Java updateUI 只工作一次

转载 作者:行者123 更新时间:2023-12-01 17:30:24 25 4
gpt4 key购买 nike

这是我正在构建的应用程序 https://github.com/chrisbramm/LastFM-History-Graph

下面是 src/lastfmhistoryclasses 中 Controller 类的一部分。当OutputGUIView创建后它会创建三个组件,一个 JPanel graphPanel ,这被添加到 JScrollPane graphScrollPanel另一个JPanel autocompletePanel 。然后将这些全部添加到 JFrame OutputGUIView 。然后,下面的监听器更改 graphPanel 的首选大小当您第一次按下按钮时,UI 会更新以显示 graphPanel graphScrollPanel 的大小和滚动条已增加有零钱。

但是现在,如果您按另一个按钮,首选尺寸会发生变化,但 UI 不会更新,如果您通过最大化窗口尺寸来更改窗口尺寸,它就会更新。

class Zoom2000 implements ActionListener{
public void actionPerformed(ActionEvent e){
outputGUIView.graphPanel.setPreferredSize(new Dimension(screenWidth, 2000));
outputGUIView.graphScrollPanel.updateUI();

}
}
class ZoomDefault implements ActionListener{
public void actionPerformed(ActionEvent e){
outputGUIView.graphPanel.setPreferredSize(new Dimension(screenWidth, screenHeight));
outputGUIView.graphScrollPanel.updateUI();


}
}
class Zoom6000 implements ActionListener{
public void actionPerformed(ActionEvent e){
outputGUIView.graphPanel.setPreferredSize(new Dimension(screenWidth, 6000));
outputGUIView.graphScrollPanel.updateUI();

}
}

我也尝试过不同的事情,例如 invalidate/validate/revalidate (并重新绘制)始终在各种组件上,而 graphPanel 只是坐在那里,并且仅在您更改窗口尺寸时才重新绘制。

知道我做错了什么吗?

编辑更新:这是 GraphPanel 类:

package lastfmhistoryguis;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import javax.swing.*;

import de.umass.lastfm.*;
import lastfmhistoryclasses.*;

SuppressWarnings("serial")
public class GraphPanel extends JPanel {

private LastFMHistory graphData;
private int graphHeight;
private int graphWidth;
private int zoom;
private final int PAD = 20;

public GraphPanel(LastFMHistory model, int zoom){
this.graphData = model;
if (zoom != 1){
this.zoom = zoom;
}else{
this.zoom = 1;
System.out.println("getHeight() returning:" + getHeight());
}
System.out.println("Width" + getWidth() + "Height" + getHeight());

}

protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Drawing");
Graphics2D graph = (Graphics2D) g;

if (graphData == null) {
System.err.println("No data found");
} else {
System.out.println("paintComponent Width" + getWidth() + "Height" + getHeight());
graphWidth = getWidth() - 5 * PAD;
//graphHeight = getHeight() - 2 * PAD;
graphHeight = 6000 - 2* PAD;
System.out.println(graphWidth + ", " + graphHeight);

int x0 = graphWidth + PAD;
graph.draw(new Rectangle2D.Double(PAD, PAD, graphWidth, graphHeight));
double xInc = (double) (graphWidth) / (graphData.dayMax);
double secondHeight = (double) (graphHeight) / 86400;

for (int i = 0; i <= 86400; i++) {
if (i % 3600 == 0) {
graph.draw(new Line2D.Double(x0, (i * secondHeight) + PAD,
x0 + 10, (i * secondHeight) + PAD));
String hour = Integer.toString(i / 3600);
graph.drawString(hour, x0 + 15,
(int) ((i * secondHeight) + PAD));
}
}

for (Track t : graphData.history) {
if (t.getPlayedWhen() != null) {

Color color = t.getColour();

int duration = t.getDuration();
int day = Math.abs(t.getDay());
double dayOrigin = x0 - ((day + 1) * xInc);
double timeOrigin = t.getGraphHeight() * secondHeight + PAD;
double trackHeight = duration * secondHeight;
graph.setColor(color);
// System.out.println("PLOTTING TRACK, " + day + ", " +
// dayOrigin + ", " + t.getGraphHeight() + ", " + timeOrigin
// + ", " + trackHeight);
// graph.draw(new Rectangle2D.Double(dayOrigin, timeOrigin,
// xInc, trackHeight));
graph.fillRect((int) dayOrigin, (int) timeOrigin,
(int) xInc, (int) trackHeight);
}

}

for (int i = 0; i < graphData.dayMax;){
graph.draw(new Line2D.Double(x0 - i * xInc, PAD, x0 - i * xInc, graphHeight + PAD));
i = i + 7;
}

}
}
public void zoom(int zoom){
this.zoom = zoom;
repaint();
}

}

它创建一个 Graphics2D 对象,在该对象上绘制一个大的轮廓矩形,然后将每个轨道矩形绘制到此 Graphics2D 图形对象上的某处。现在我已经删除了 setPreferredSize as recommended here 的使用但现在我遇到的问题是,当我手动将 GraphPanel 中的 graphHeight 设置为高度(例如 6000)时,graphScrollPanel 没有意识到它包含的 graphPanel 实际上更大,因为 graphHeight 所做的只是绘制一个约 6000px 高的矩形。那么在这种情况下我应该使用 setPreferredSize 还是有其他方法来设置 Graphics2D 对象的大小?

最佳答案

不要调用updateUI,这与 UI Look and Feel API 相关,与重画关系不大。

您尝试过/正在使用哪些布局管理器?

调用invalidate()repaint()应该会影响父容器布局管理器并导致它们相应地重新布局组件,但您需要记住,布局管理器仅使用最小/最大/首选项尺寸信息作为指导。

从你的例子中我最好的客人是你应该尝试打电话

outputGUIView.graphPanel.invalidate();
outputGUIView.graphPanel.repaint();

和/或

outputGUIView.invalidate();
outputGUIView.repaint();

在滚动 Pane 中调用 invalidate 可能不会有太大效果,因为视口(viewport)负责布局内容,而不是滚动 Pane 。

如果你真的很绝望,你可以尝试

outputGUIView.graphScrollPanel.getViewport().invalidate();
outputGUIView.graphScrollPanel.getViewport().repaint();

关于Java updateUI 只工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11640494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com