1

这就是我想要实现的目标:

在此处输入图像描述

如您所见,水平滚动已更改,应在同一行中添加 JLabel("text")。目前我找到了改变水平滚动的方法(比如在图像上),但我找不到任何方法在它放置在图像上的地方添加 JLabel("text")。

有什么建议么?提前致谢!

import java.awt.Component;
import java.awt.Container;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneLayout;
import javax.swing.WindowConstants;

public class Test {

    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.setSize(300, 300);

        JPanel myPanel = new JPanel();
        myPanel.add(new JLabel("Check Check Check Check Check Check Check Check"));
        MyScrollPane scrollPane = new MyScrollPane(myPanel);

        jFrame.add(scrollPane);
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    }

}

class MyScrollPane extends JScrollPane {

    JLabel label = new JLabel("text");

    public MyScrollPane(Component view) {
        super(view, VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_ALWAYS);
        this.setLayout(new MyLayout(label));
        add(label);
    }
}

class MyLayout extends ScrollPaneLayout {

    JLabel label;

    public MyLayout(JLabel aLabel) {
        super();
        label = aLabel;
    }

    public void layoutContainer(Container parent) {
        super.layoutContainer(parent);

        hsb.setSize(hsb.getWidth() - 100, hsb.getHeight()); // drift
        Point location = hsb.getLocation();
        label.setLocation(location.x + 12, location.y - 12);
    }
}
4

3 回答 3

3

您可能要考虑制作自己的 JScrollPane 实现。听起来可能很吓人,但本质上,一个 JScrollPane 就是 2 个 JScrollBars 和一些调用 g.translate() 的图形逻辑 如果你玩弄 g.translate,你会发现滚动你自己的东西非常容易。

制作自己的组件的优点是您可以完全控制布局、显示和事件。如果我处于你的位置,这就是我会采取的路线。

于 2012-04-25T20:33:10.433 回答
2

这是我的尝试:

import java.awt.*;
import java.awt.font.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test2 {
  public JComponent makeUI() {
    JPanel myPanel = new JPanel();
    myPanel.add(new JLabel("Check Check Check Check Check Check Check Check"));
    JScrollPane scrollPane = new JScrollPane(myPanel,
        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    JScrollBar hsb = scrollPane.getHorizontalScrollBar();
    hsb.setBorder(new StringBorder(hsb, "Test"));
    JPanel p = new JPanel(new BorderLayout());
    p.add(scrollPane);
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new Test2().makeUI());
    f.setSize(300, 300);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}
class StringBorder implements Border {
  private final JComponent parent;
  private final Insets insets;
  private final Rectangle rect;
  private final String str;
  public StringBorder(JComponent parent, String str) {
    this.parent = parent;
    this.str = str;
    FontRenderContext frc = new FontRenderContext(null, true, true);
    rect = parent.getFont().getStringBounds(str, frc).getBounds();
    rect.width = Math.max(rect.width, 100);
    insets = new Insets(0,5,0,rect.width);
  }
  @Override public Insets getBorderInsets(Component c) {
    return insets;
  }
  @Override public boolean isBorderOpaque() {
    return false;
  }
  @Override public void paintBorder(
      Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D)g;
    float tx = x + width - insets.right + insets.left;
    float ty = y - rect.y + (height - rect.height)/2;
    g2.setPaint(Color.BLACK);
    g2.drawString(str, tx, ty);
  }
}
于 2012-04-26T08:11:57.807 回答
0

可能实现此类目标的最佳方法是将您自己的布局与JScrollPane. 这是一个允许任何组件作为左下角组件的示例:

public class CustomScrollPaneLayout extends ScrollPaneLayout {
    @Override
    public void layoutContainer(Container parent) {
        super.layoutContainer(parent);

        JScrollBar scrollBar = getHorizontalScrollBar();
        if (lowerLeft == null || !lowerLeft.isVisible() || scrollBar == null)
            return;

        Dimension size = lowerLeft.getPreferredSize();
        Rectangle bounds = lowerLeft.isVisible()
                ? lowerLeft.getBounds() : scrollBar.getBounds();
        if (size.width > bounds.getWidth()) {
            int right = scrollBar.getX()+scrollBar.getWidth();
            if (size.width + scrollBar.getMinimumSize().width > right)
                size.width = right - scrollBar.getMinimumSize().width;
            if (bounds.x + size.width < scrollBar.getX())
                size.width = scrollBar.getX() - bounds.x;

            lowerLeft.setBounds(bounds.x, bounds.y, size.width, bounds.height);
            int x = bounds.x + size.width;
            scrollBar.setBounds(x, bounds.y, right - x, bounds.height);
        }
        lowerLeft.setVisible(true);
    }
}

请注意,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS如果您希望控件始终可见,则需要使用水平滚动条策略。

于 2016-03-02T11:42:27.567 回答