如何强制JScrollPane中的组件显示

汤姆

我在显示放置在JScrollPane中的特定组件时遇到问题。我有带有GridLayout(1,0)的水平JScrollPane,它包含可变数量的JPanels-每个均包含图像。就像GIF图片中的帧预览一样。我使用按钮在这些JPanel之间移动(通过更改边框和保持所选索引的索引),但是我不知道如何强制JScrollPane向我显示JPanel(如果已选择)(并尽可能居中)。

所以我要这个 在此处输入图片说明

强制执行此操作: 在此处输入图片说明

提前致谢!

编辑:几乎与scrollRectToVisible()方法一起工作的代码

public class MiniatursPanel extends JPanel{


private int indexOfChosenFrame = 0;
private ArrayList<JPanel> frames;
private JScrollPane scrollPane;
private JPanel innerPanel;



public MiniatursPanel(){
    setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(),BorderFactory.createLoweredBevelBorder()));
    setPreferredSize(new Dimension(1200,170));
    setLayout(null);     
}

public void initialize(){
    int width = GifImageStats.getInstance().getWidth();
    int height = GifImageStats.getInstance().getHeight();
    int numberOfFrames = GifImageStats.getInstance().getNumberOfFrames();

    frames = new ArrayList(numberOfFrames);

    for (int i = 0; i < numberOfFrames; i++) {
        JPanel frameBox = new JPanel();
        frameBox.setLayout(new FlowLayout(FlowLayout.CENTER));
        JButton button = new JButton(String.valueOf(i+1));
        button.setPreferredSize(new Dimension(2*width,2*height));
        button.setBackground(Color.white);
        button.setFocusable(false);
        frameBox.add(button);
        frames.add(frameBox);
    }

    innerPanel = new JPanel();
    innerPanel.setLayout(new GridLayout(1,0,10,10));


    for (JPanel button : frames) {
        innerPanel.add(button);
    }

    scrollPane = new JScrollPane(innerPanel);
    scrollPane.setBounds(10, 10, 1180, 145);
    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);

    highlightFrame(frames.get(0));

    add(scrollPane);
}


public void nextFrame(){
    if (indexOfChosenFrame == frames.size() - 1) {           
        unhighlightFrame(frames.get(indexOfChosenFrame));
        indexOfChosenFrame = 0;
        highlightFrame(frames.get(0));
    }else{
        unhighlightFrame(frames.get(indexOfChosenFrame));
        indexOfChosenFrame++;
        highlightFrame(frames.get(indexOfChosenFrame));
    }
}

public void previousFrame(){
    if (indexOfChosenFrame == 0) {           
        unhighlightFrame(frames.get(0));
        indexOfChosenFrame = frames.size()-1;
        highlightFrame(frames.get(indexOfChosenFrame));
    }else{
        unhighlightFrame(frames.get(indexOfChosenFrame));
        indexOfChosenFrame--;
        highlightFrame(frames.get(indexOfChosenFrame));
    }
}

private void highlightFrame(JPanel frame){
    Rectangle rect = frame.getBounds();
    rect.setBounds(frame.getX()-550, frame.getY(), frame.getWidth()+1050, frame.getHeight());
    innerPanel.scrollRectToVisible(rect);     
    frame.setBorder(BorderFactory.createLineBorder(Color.red,2));
}          

private void unhighlightFrame(JPanel frame){
    frame.setBorder(null);
}
马可13

这里的相关方法是JComponent#scrollRectToVisible(Rectangle)必须在滚动窗格的视口中的组件上调用它。(在您的情况下,这是具有网格布局的面板,其中包含其他子面板)。

传递给此方法的矩形可以是一个子面板的边界。在这种情况下,scoll窗格将进行“最小”滚动,使给定矩形可见。如果要确保相应的子面板位于中心,则可以增加此矩形的大小-也就是说,以所需子面板位于中心的方式定义一个矩形。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class ScrollToVisible
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        int n = 20;
        final JPanel panel = new JPanel(new GridLayout(1,0));
        final List<JComponent> components = new ArrayList<JComponent>();
        for (int i=0; i<n; i++)
        {
            JComponent component = new JLabel(String.valueOf(i), SwingConstants.CENTER);
            component.setPreferredSize(new Dimension(100,100));
            component.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            components.add(component);
            panel.add(component);
        }
        final JScrollPane scrollPane = new JScrollPane(panel);

        final JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, n-1, 1));
        spinner.addChangeListener(new ChangeListener()
        {
            JComponent selectedComponent = components.get(0);

            @Override
            public void stateChanged(ChangeEvent e)
            {
                selectedComponent.setBorder(BorderFactory.createLineBorder(Color.BLACK));

                int index = (Integer)spinner.getValue();
                JComponent component = components.get(index);
                Rectangle bounds = component.getBounds();

                // This would make the component "just" visible:
                //panel.scrollRectToVisible(bounds);

                // This will center the component:
                int cx = bounds.x + bounds.width / 2;
                int w = scrollPane.getViewport().getWidth();
                Rectangle r = new Rectangle(cx-w/2, bounds.y, w, bounds.height);
                panel.scrollRectToVisible(r);


                selectedComponent = component;
                selectedComponent.setBorder(BorderFactory.createLineBorder(Color.RED));

            }
        });

        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        f.getContentPane().add(spinner, BorderLayout.NORTH);


        f.setSize(800, 300);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

}

编辑:您应使用setLayout(null),你应该不会做手工调用setBounds,你应该很少使用setPreferredSize而且...当您发布的代码已经非常接近https://stackoverflow.com/help/mcve(甚至是从另一篇文章的可运行示例创建的)时,您应该使其真正可运行。重新插入样板代码并浪费一些时间进行调试很烦人,直到您意识到initialize()根本没有调用...

但是,根据此更改代码:

private void highlightFrame(JPanel frame){
    Rectangle rect = frame.getBounds();

    int c = rect.x + rect.width / 2; 
    int w = scrollPane.getViewport().getWidth();
    int x = c-w/2;
    rect.setBounds(x, rect.y, w, rect.height);

    innerPanel.scrollRectToVisible(rect);     
    frame.setBorder(BorderFactory.createLineBorder(Color.red,2));
}          

private void unhighlightFrame(JPanel frame){
    frame.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
}

最重要的是,通过设置一个与“突出显示”边框相同大小的空边框来确保组件的大小正确。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

JScrollPane中消失的组件

来自分类Dev

如何强制刷新/重新绘制JScrollPane?

来自分类Dev

如何强制 ListBoxItems 在 XAML 中内联显示

来自分类Dev

JScrollPane中的JPanel不显示

来自分类Dev

React:如何在功能组件中强制状态更新?

来自分类Dev

如何使水平滚动条出现在包含JTextPane组件的JScrollPane中

来自分类Dev

如何在reactjs中显示多个组件

来自分类Dev

如何在样式组件中显示背景?

来自分类Dev

如何使组件显示在可拖动组件列表中(对于parsys)?

来自分类Dev

JScrollPane-如何显示JTable标头?

来自分类Dev

JScrollPane中的JTextArea将不会显示

来自分类Dev

JScrollPane将不会显示在JTextArea中

来自分类Dev

在JScrollPane中显示表的列标题

来自分类Dev

使用Aspose在JScrollPane中显示PDF

来自分类Dev

JScrollPane中的JTextArea将不会显示

来自分类Dev

JTable标头未显示在JScrollPane中

来自分类Dev

如何在Julia的REPL中强制显示该横幅消息?

来自分类Dev

如何强制For loop()或lapply()在R中显示错误消息

来自分类Dev

如何在Android WebView中强制显示深色网页?

来自分类Dev

如何强制Chrome在辅助显示屏中打开?

来自分类Dev

如何在Julia的REPL中强制显示该横幅消息?

来自分类Dev

如何在Highcharts中强制显示x轴标签?

来自分类Dev

如何强制 aptitude 将每个搜索结果显示在多行中?

来自分类Dev

如何在一个JScrollPane中显示多个可选图像?

来自分类Dev

使用按钮映射时,如何通过子组件中的按钮显示/隐藏父组件中的组件?

来自分类Dev

使用按钮映射时,如何通过子组件中的按钮显示/隐藏父组件中的组件?

来自分类Dev

同时将组件作为prop传递时,如何在TypeScript(在React中)中强制传递prop?

来自分类Dev

有JScrollPane时如何定位Java swing组件

来自分类Dev

如何使MPC显示强制字幕?

Related 相关文章

  1. 1

    JScrollPane中消失的组件

  2. 2

    如何强制刷新/重新绘制JScrollPane?

  3. 3

    如何强制 ListBoxItems 在 XAML 中内联显示

  4. 4

    JScrollPane中的JPanel不显示

  5. 5

    React:如何在功能组件中强制状态更新?

  6. 6

    如何使水平滚动条出现在包含JTextPane组件的JScrollPane中

  7. 7

    如何在reactjs中显示多个组件

  8. 8

    如何在样式组件中显示背景?

  9. 9

    如何使组件显示在可拖动组件列表中(对于parsys)?

  10. 10

    JScrollPane-如何显示JTable标头?

  11. 11

    JScrollPane中的JTextArea将不会显示

  12. 12

    JScrollPane将不会显示在JTextArea中

  13. 13

    在JScrollPane中显示表的列标题

  14. 14

    使用Aspose在JScrollPane中显示PDF

  15. 15

    JScrollPane中的JTextArea将不会显示

  16. 16

    JTable标头未显示在JScrollPane中

  17. 17

    如何在Julia的REPL中强制显示该横幅消息?

  18. 18

    如何强制For loop()或lapply()在R中显示错误消息

  19. 19

    如何在Android WebView中强制显示深色网页?

  20. 20

    如何强制Chrome在辅助显示屏中打开?

  21. 21

    如何在Julia的REPL中强制显示该横幅消息?

  22. 22

    如何在Highcharts中强制显示x轴标签?

  23. 23

    如何强制 aptitude 将每个搜索结果显示在多行中?

  24. 24

    如何在一个JScrollPane中显示多个可选图像?

  25. 25

    使用按钮映射时,如何通过子组件中的按钮显示/隐藏父组件中的组件?

  26. 26

    使用按钮映射时,如何通过子组件中的按钮显示/隐藏父组件中的组件?

  27. 27

    同时将组件作为prop传递时,如何在TypeScript(在React中)中强制传递prop?

  28. 28

    有JScrollPane时如何定位Java swing组件

  29. 29

    如何使MPC显示强制字幕?

热门标签

归档