java - 重绘内容 Pane 后设置 JScrollPane 的滚动位置

标签 java swing scroll jpanel jscrollpane

我有一个 JScrollPane,其中有一个 JPanel,它显示类似时间表的内容。该时间表面板可缩放和滚动。我在这个时间表面板中有很多条目,每个条目都是一个自己的面板,并且有开始时间和长度。

现在,当我单击此时间表中的某个条目时,我想放大该条目,当然也可以移动到它。

例如:实际缩放显示从一月到三月的3个月。现在我有一个从 3 月 1 日到 3 月 3 日的条目。例如,该条目现在的长度为 10 像素。当我单击此条目时,缩放系数会以这种方式更改,时间表仅显示 3 天并从 3 月 1 日开始,因此条目宽度超过整个滚动 Pane View 端口。

为此,我计算新的缩放系数和时间表面板的新开始 X 位置,并调用面板的重新绘制。

这适用于缩放,但由于此时时间表面板没有新的宽度,这导致滚动 Pane 滚动条没有新的尺寸。所以我无法在代码的这一点设置新的滚动条位置。

那么,在滚动 Pane 重绘完成并且滚动条具有新尺寸之后,如何设置正确的滚动条位置?

这是一些用于更多理解的伪代码(对格式感到抱歉,但我没有设法粘贴代码以使缩进正确):

public class MyRootPanel extends JPanel
{
TimeSheetPanel tsPanel = new TimeSheetPanel(this);
tsPanel.setLayout(null);

scrollPanel=new JScrollPane(tsPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
this.add(scrollPanel);

public setScrollPos(int xPos)
{
    scrollPanel.getHorizontalScrollBar().setValue(xPos);
}
}

public class TimeSheetPanel extends JPanel
{
MyRootPanel rootPanel;

public int pixelPerHour = 5; // Zoom factor
public int rowHeight = 30; // height of one row on table

public TimeSheetPanel(MyRootPanel root)
{
    rootPanel = root;

    this.setLayout(null);
    setBounds(0,0, maxDays * pixelPerHour *24, maxrows * rowHeight);

    for(Entry e : entryList)
    {
        EntryPanel entryPanel = new EntryPanel(this, entry);
        this.add(entryPanel);
    }
}

public void zoomToEntry(Entry entry)
{
    // calc new zoom factor here.
    pixelPerHour = ......
    newXPos = .....
    // and set it to the panel
    setBounds(0,0, maxDays * pixelPerHour *24, maxrows * rowHeight);
    // call repaint
    repaint();
    // THIS WILL NOT WORK
    rootPanel.setScrollPos(newXPos);
}

}

public class EntryPanel extends JPanel
{
TimeSheetPanel parentPanel;
Entry entry;

public EntryPanel(TimeSheetPanel parent, Entry e)
{
    parentPanel = parent;
    Entry = e;

    this.setLayout(null);

    int left = entry.start * parentPanel.pixelPreHour;
    int width = entry.length * parentPanel.pixelPerHour;
    int top = entry.row * parentPanel.rowHeight;
    int height = parentPanel.rowHeight;

    setBounds(left, top, width, height);

    addMouseListener(this);

}

@Override
public void mouseClicked(MouseEvent e)
{
    if (e.getClickCount() == 2)  
    {
        parentPanel.zoomToEntry(entry);
    }
}
}

最佳答案

对于任何寻找答案的人,我通过使用 invokeLater 解决了我的问题

    repaint();
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run() 
        {
            valuePanelScrollPane.getHorizontalScrollBar().setValue(xpos);
            valuePanelScrollPane.getVerticalScrollBar().setValue(ypos);
        }
    });

关于java - 重绘内容 Pane 后设置 JScrollPane 的滚动位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38418728/

相关文章:

javascript - 使用 jQuery 滚动到某个元素

java - 使用 GSON 从 Java 中的 JSON 字符串获取值

javascript - 视差效果渲染问题

java - 如何将 JTable 滚动到特定值?

java - 在我的屏幕上放置重新启动按钮

Java:JButton 打开另一个我可以输入的 JFrame

java - 当 setMaximumSize() 和 setPreferedSize() 不起作用时,如何对 JComponent 设置硬限制?

Java 循环泛型

java - Web 服务器 java 库?

java - 性能:Java 与数据库