关于java中的JScrollPane的问题

csu_NO1_java 2010-11-09 09:48:00
现在遇到一个问题,在JScrollPane中,如何
去掉垂直方向滚动条的向上和向下的两个按钮,使得只能显示滚动条,
在页面没有滑动的时候,滚动条是不可见的,页面是通过鼠标拖动进行滑动的,
当页面滚动的时候,滑动条可见,并且随着页面一起向上或者向下滑动,
在滑动过程中滚动条根据页面滑动的距离变换长短。
...全文
272 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
csu_NO1_java 2010-11-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sunyiz 的回复:]
原来楼主在这里也发了帖子啊
现在改成了Box的结构、
至于对于拖动速度的控制
我发现一个问题,当mouseDragged事件的时候
e的Y坐标几乎是一种指数型的变化,
所以我这个例子会感觉拖动的愈来愈快
这个问题我们可以一起研究一下


Java code
import java.awt.Color;
import java.awt.Container;
import ja……
[/Quote]


先前在办公室,不太方便,前面写的代码先前没有多想,没有很好的解决,刚回到住的地方,细想了下
觉得先前的思路不对。重新写了一下这个代码,现在应该是比较好的解决了这个问题了。能够做到跟我们平时拖动滚动条时的滚动效果一样。
主要在于要转换坐标,把鼠标事件的坐标转换到JScrollpane上面,然后拖动鼠标产生的高度差就是滑动条在JScrollpane上面所移动的像素,完全跟拖动滑动条的效果是一样的。不知道描述清楚没有,现在贴代码

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicScrollBarUI;

public class Test extends JFrame{

private static final long serialVersionUID = 1L;
private Container content = null;
private JTextArea area = null;
private JScrollPane scrMain = null;
private Point offsetV;
private int hy;
private int value;
public Test() {
initialize();
}

private void initialize() {
setSize(774, 740);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContent();
setVisible(true);
}

public static void main(String[] args) {
Test test = new Test();
test.setVisible(true);
}

public Container getContent() {
if (content == null) {
content = getContentPane();
content.setLayout(null);
area = new JTextArea();
area.setText("0");
for (int i=1;i<1000;i++) {
area.append("\n" + i);
}
scrMain = new JScrollPane(area);

scrMain.setBounds(0, 0, 770, 706);
scrMain.getVerticalScrollBar().setUI(new MyScrollBarUI());
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
area.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
// offsetV = e.getPoint();
offsetV = SwingUtilities.convertPoint((JTextArea)e.getSource(), e.getPoint(), ((JTextArea)e.getSource()).getParent());
hy = offsetV.y;
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
}
public void mouseReleased(MouseEvent e) {
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
}
});
area.addMouseMotionListener(new MouseMotionListener(){

public void mouseDragged(MouseEvent e) {
value = scrMain.getVerticalScrollBar().getValue();
//int y = (e.getY() - offsetV.y)/20 + (scrMain.getVerticalScrollBar().getValue());
int y = 0;
Point newPoint = SwingUtilities.convertPoint((JTextArea)e.getSource(), e.getPoint(), ((JTextArea)e.getSource()).getParent());

int my = (newPoint.y - hy);
y = value + my;
if(y > scrMain.getVerticalScrollBar().getMaximum()){
y = scrMain.getVerticalScrollBar().getMaximum();
}
if (y < 0) {
y = 0;
}
hy = newPoint.y;
scrMain.getVerticalScrollBar().setValue(y);
}
public void mouseMoved(MouseEvent e) {
}
});
content.add(scrMain);
}
return content;
}

class MyScrollBarUI extends BasicScrollBarUI {
@Override
protected JButton createDecreaseButton(int orientation) {
return new MyArrowButton(orientation, //用自己的箭头替代默认的
UIManager.getColor("ScrollBar.thumb"),
UIManager.getColor("ScrollBar.thumbShadow"),
UIManager.getColor("ScrollBar.thumbDarkShadow"),
UIManager.getColor("ScrollBar.thumbHighlight"));
}

@Override
protected JButton createIncreaseButton(int orientation) {
return new MyArrowButton(orientation, //用自己的箭头替代默认的
UIManager.getColor("ScrollBar.thumb"),
UIManager.getColor("ScrollBar.thumbShadow"),
UIManager.getColor("ScrollBar.thumbDarkShadow"),
UIManager.getColor("ScrollBar.thumbHighlight"));
}

//这是绘制拖动条的部分
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
super.paintThumb(g, c, thumbBounds);
//觉得原来的拖动条难看可以重写这个方法,下面是我重画的一个例子
g.setColor(Color.LIGHT_GRAY);
// g.setColor(Color.black);
g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height);
g.setColor(Color.GRAY);
g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height-1);
g.setColor(Color.WHITE);
g.drawRect(thumbBounds.x+1, thumbBounds.y+1, thumbBounds.width-2, thumbBounds.height-3);
}
}

//重写箭头按钮,把默认大小设为0
class MyArrowButton extends BasicArrowButton {
private static final long serialVersionUID = 1L;
public MyArrowButton(int direction, Color background, Color shadow,
Color darkShadow, Color highlight) {
super(direction, background, shadow, darkShadow, highlight);
}

@Override
public Dimension getPreferredSize() {//将箭头默认大小设成0
return new Dimension(0, 0);
}

@Override
public Dimension getMinimumSize() {//将箭头最小大小设成0
return new Dimension(0, 0);
}
}
}
csu_NO1_java 2010-11-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sunyiz 的回复:]
原来楼主在这里也发了帖子啊
现在改成了Box的结构、
至于对于拖动速度的控制
我发现一个问题,当mouseDragged事件的时候
e的Y坐标几乎是一种指数型的变化,
所以我这个例子会感觉拖动的愈来愈快
这个问题我们可以一起研究一下


Java code
import java.awt.Color;
import java.awt.Container;
import ja……
[/Quote]


把你之前的代码改了一下,由于是在公司的公用上网机上,所以只是把你之前给我的代码改了下,这次的代码我转回去再看下:

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicScrollBarUI;

public class Test extends JFrame{

private static final long serialVersionUID = 1L;
private Container content = null;
private JTextArea area = null;
private JScrollPane scrMain = null;
private Point offsetV;
private int hy;
private int value;
public Test() {
initialize();
}

private void initialize() {
setSize(774, 740);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContent();
setVisible(true);
}

public static void main(String[] args) {
Test test = new Test();
test.setVisible(true);
}

public Container getContent() {
if (content == null) {
content = getContentPane();
content.setLayout(null);
area = new JTextArea();
area.setText("0");
for (int i=1;i<1000;i++) {
area.append("\n" + i);
}
scrMain = new JScrollPane(area);

scrMain.setBounds(0, 0, 770, 706);
scrMain.getVerticalScrollBar().setUI(new MyScrollBarUI());
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
area.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
offsetV = e.getPoint();
hy = offsetV.y;
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
}
public void mouseReleased(MouseEvent e) {
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
}
});
area.addMouseMotionListener(new MouseMotionListener(){
//拖动的实现,速度没控制好,不过可以将就着看出效果
public void mouseDragged(MouseEvent e) {
value = scrMain.getVerticalScrollBar().getValue();
//int y = (e.getY() - offsetV.y)/20 + (scrMain.getVerticalScrollBar().getValue());
int y = 0;

int my = (e.getY() - hy)/2;
System.out.println(my);
if(my > 0){
y = value + my;
if(y > scrMain.getVerticalScrollBar().getMaximum()){
y = scrMain.getVerticalScrollBar().getMaximum();
}
}else{
y = value + my;
if (y < 0) {
y = 0;
}
}

/*System.out.println(y);
if (y > scrMain.getVerticalScrollBar().getMaximum()) {
y = scrMain.getVerticalScrollBar().getMaximum();
} else if (y < 0) {
y = 0;
}*/
hy = e.getY();
scrMain.getVerticalScrollBar().setValue(y);
}
public void mouseMoved(MouseEvent e) {
}
});
content.add(scrMain);
}
return content;
}

class MyScrollBarUI extends BasicScrollBarUI {
@Override
protected JButton createDecreaseButton(int orientation) {
return new MyArrowButton(orientation, //用自己的箭头替代默认的
UIManager.getColor("ScrollBar.thumb"),
UIManager.getColor("ScrollBar.thumbShadow"),
UIManager.getColor("ScrollBar.thumbDarkShadow"),
UIManager.getColor("ScrollBar.thumbHighlight"));
}

@Override
protected JButton createIncreaseButton(int orientation) {
return new MyArrowButton(orientation, //用自己的箭头替代默认的
UIManager.getColor("ScrollBar.thumb"),
UIManager.getColor("ScrollBar.thumbShadow"),
UIManager.getColor("ScrollBar.thumbDarkShadow"),
UIManager.getColor("ScrollBar.thumbHighlight"));
}

//这是绘制拖动条的部分
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
super.paintThumb(g, c, thumbBounds);
//觉得原来的拖动条难看可以重写这个方法,下面是我重画的一个例子
g.setColor(Color.LIGHT_GRAY);
// g.setColor(Color.black);
g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height);
g.setColor(Color.GRAY);
g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height-1);
g.setColor(Color.WHITE);
g.drawRect(thumbBounds.x+1, thumbBounds.y+1, thumbBounds.width-2, thumbBounds.height-3);
}
}

//重写箭头按钮,把默认大小设为0
class MyArrowButton extends BasicArrowButton {
private static final long serialVersionUID = 1L;
public MyArrowButton(int direction, Color background, Color shadow,
Color darkShadow, Color highlight) {
super(direction, background, shadow, darkShadow, highlight);
}

@Override
public Dimension getPreferredSize() {//将箭头默认大小设成0
return new Dimension(0, 0);
}

@Override
public Dimension getMinimumSize() {//将箭头最小大小设成0
return new Dimension(0, 0);
}
}
}



试了一下int my = (e.getY() - hy)/2;这个地方,要是没有除以2的话还是感觉有点快,你看下有没有问题
csu_NO1_java 2010-11-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sunyiz 的回复:]
原来楼主在这里也发了帖子啊
现在改成了Box的结构、
至于对于拖动速度的控制
我发现一个问题,当mouseDragged事件的时候
e的Y坐标几乎是一种指数型的变化,
所以我这个例子会感觉拖动的愈来愈快
这个问题我们可以一起研究一下


Java code
import java.awt.Color;
import java.awt.Container;
import ja……
[/Quote]

很感谢你,现在我已经实现了想要的效果。
滑动我是这样控制的:
记录下鼠标每次拖拽的距离,即像素,然后把
crollBar.getValue();的值加上或者减去每次拖拽的像素,
再把这个更新后的value设置到scrollBar.setValue(value);
这样的效果看起来比较平滑,呵呵
sunyiz 2010-11-10
  • 打赏
  • 举报
回复
原来楼主在这里也发了帖子啊
现在改成了Box的结构、
至于对于拖动速度的控制
我发现一个问题,当mouseDragged事件的时候
e的Y坐标几乎是一种指数型的变化,
所以我这个例子会感觉拖动的愈来愈快
这个问题我们可以一起研究一下

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicScrollBarUI;

public class MyScrPane extends JFrame{

private static final long serialVersionUID = 1L;
private Container content = null;
private JScrollPane scrMain = null;
private Point offsetV;
private JLabel[] labs = null;
private Box box = null;

public MyScrPane() {
initialize();
}

private void initialize() {
setSize(774, 740);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContent();
setVisible(true);
}

public static void main(String[] args) {
MyScrPane test = new MyScrPane();
test.setVisible(true);
}

public Container getContent() {
if (content == null) {
content = getContentPane();
content.setLayout(null);
box = new Box(BoxLayout.Y_AXIS);
labs = new JLabel[200];
for (int i=0;i<labs.length;i++) {
labs[i] = new JLabel(""+i);
box.add(labs[i]);
}
scrMain = new JScrollPane(box);
scrMain.setBounds(0, 0, 770, 706);
scrMain.getVerticalScrollBar().setUI(new MyScrollBarUI());
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
box.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
offsetV = e.getPoint();
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
}
public void mouseReleased(MouseEvent e) {
scrMain.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
}
});
box.addMouseMotionListener(new MouseMotionListener(){
//拖动的实现,速度没控制好,不过可以将就着看出效果
public void mouseDragged(MouseEvent e) {
int y = (e.getY() - offsetV.y)/20 + scrMain.getVerticalScrollBar().getValue();
if (y > scrMain.getVerticalScrollBar().getMaximum()) {
y = scrMain.getVerticalScrollBar().getMaximum();
} else if (y < 0) {
y = 0;
}
scrMain.getVerticalScrollBar().setValue(y);
}
public void mouseMoved(MouseEvent e) {
}
});
content.add(scrMain);
}
return content;
}

class MyScrollBarUI extends BasicScrollBarUI {
@Override
protected JButton createDecreaseButton(int orientation) {
return new MyArrowButton(orientation, //用自己的箭头替代默认的
UIManager.getColor("ScrollBar.thumb"),
UIManager.getColor("ScrollBar.thumbShadow"),
UIManager.getColor("ScrollBar.thumbDarkShadow"),
UIManager.getColor("ScrollBar.thumbHighlight"));
}

@Override
protected JButton createIncreaseButton(int orientation) {
return new MyArrowButton(orientation, //用自己的箭头替代默认的
UIManager.getColor("ScrollBar.thumb"),
UIManager.getColor("ScrollBar.thumbShadow"),
UIManager.getColor("ScrollBar.thumbDarkShadow"),
UIManager.getColor("ScrollBar.thumbHighlight"));
}

//这是绘制拖动条的部分
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
super.paintThumb(g, c, thumbBounds);
//觉得原来的拖动条难看可以重写这个方法,下面是我重画的一个例子
g.setColor(Color.LIGHT_GRAY);
g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height);
g.setColor(Color.GRAY);
g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height-1);
g.setColor(Color.WHITE);
g.drawRect(thumbBounds.x+1, thumbBounds.y+1, thumbBounds.width-2, thumbBounds.height-3);
}
}

//重写箭头按钮,把默认大小设为0
class MyArrowButton extends BasicArrowButton {
private static final long serialVersionUID = 1L;
public MyArrowButton(int direction, Color background, Color shadow,
Color darkShadow, Color highlight) {
super(direction, background, shadow, darkShadow, highlight);
}

@Override
public Dimension getPreferredSize() {//将箭头默认大小设成0
return new Dimension(0, 0);
}

@Override
public Dimension getMinimumSize() {//将箭头最小大小设成0
return new Dimension(0, 0);
}
}
}
csu_NO1_java 2010-11-09
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 houjin_cn 的回复:]
JPanel上有子组件的话,比较麻烦,
这些JLabel中的内容你可以自己画出来,这样比较方便;
拖动效果是这样出来的, 比如一行文字最先y坐标是100, 现在要把它向下拖50, 那你就把它画在y坐标为150的地方就可以了
[/Quote]
我这里的JLabel包含在一个JPanel中,然后这个JPanel被一个Box包含,最后这个Box被另外一个JPanel包含,设为panel,现在我要把panel放到一个滚动面板中进行滚动,Box中有几十个JPanel
houjin_cn 2010-11-09
  • 打赏
  • 举报
回复
也就是所有内容都有个Y坐标的偏移量,
houjin_cn 2010-11-09
  • 打赏
  • 举报
回复
JPanel上有子组件的话,比较麻烦,
这些JLabel中的内容你可以自己画出来,这样比较方便;
拖动效果是这样出来的, 比如一行文字最先y坐标是100, 现在要把它向下拖50, 那你就把它画在y坐标为150的地方就可以了
csu_NO1_java 2010-11-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 houjin_cn 的回复:]
你要的效果跟IPhone上的效果很类似啊;
建议不用JScrollPane,
直接在内容区自己画一个滚动条就好了, 反正并不需要与这个滚动条交互,只是一个显示效果
滑动时画滚动条, 滑动完成1秒钟,再重绘一次让滚动条消失
[/Quote]

有这样考虑,但是还不知道JPanel是否有JScrollPane那样的效果,比如说,我一共有20个JLabel,但是在JPanel中只能显示出来十个,剩下的能否通过鼠标拖动显示出来。
houjin_cn 2010-11-09
  • 打赏
  • 举报
回复
你要的效果跟IPhone上的效果很类似啊;
建议不用JScrollPane,
直接在内容区自己画一个滚动条就好了, 反正并不需要与这个滚动条交互,只是一个显示效果
滑动时画滚动条, 滑动完成1秒钟,再重绘一次让滚动条消失

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧