题
我使用的是JSlider的显示在我的应用进展,以便更新为一定的处理计算。
我希望用户能够向后拖动拇指勾号在过去,但是当发生这种情况,我想进度指示器保持在其当前位置。
// A dismal attempt at drawing the situation
Progress: ---------
Thumb: |
// User drags backwards. What I have:
Progress: ---
Thumb: |
// What I want instead:
Progress: ---------
Thumb: |
任何人都可以提供如何更好地实现这一目标的任何指导? 预先感谢所有帮助!
解决方案 2
我计算出来。我扩展JSlider的从当前拇指位置分别保持跟踪的进度,然后推翻了MetalSliderUI的paintTrack方法绘制填充轨道到我想要的位置。
这里的溶液,剥离下来的重要组成部分。
新的进度条:
public class ProgressSlider extends JSlider {
protected int progress;
private static final String uiClassID = "ProgressSliderUI";
public ProgressSlider() {
progress = 0;
putClientProperty("JSlider.isFilled", Boolean.TRUE);
updateUI();
}
public void updateUI() {
setUI(new ProgressSliderUI(this));
}
public String getUIClassID() {
return uiClassID;
}
public int getProgress() {
return this.progress;
}
public void setProgress(int value) {
if (value < this.getMinimum()) {
this.progress = this.getMinimum();
}
else if (value > this.getMaximum()) {
this.progress = this.getMaximum();
}
else {
this.progress = value;
}
}
}
在新的用户界面: 注意,只有2加入到paintTrack()方法在UI类,立即注释说以下行这样。
public class ProgressSliderUI extends MetalSliderUI {
public ProgressSliderUI() {
super();
}
public ProgressSliderUI(JSlider b) {
}
@Override
public void paintTrack(Graphics g) {
Color trackColor = !slider.isEnabled() ? MetalLookAndFeel
.getControlShadow() : Color.blue;
boolean leftToRight = true;
g.translate(trackRect.x, trackRect.y);
int trackLeft = 0;
int trackTop = 0;
int trackRight = 0;
int trackBottom = 0;
// Draw the track
if (slider.getOrientation() == JSlider.HORIZONTAL) {
trackBottom = (trackRect.height - 1) - getThumbOverhang();
trackTop = trackBottom - (getTrackWidth() - 1);
trackRight = trackRect.width - 1;
}
else {
if (leftToRight) {
trackLeft = (trackRect.width - getThumbOverhang())
- getTrackWidth();
trackRight = (trackRect.width - getThumbOverhang()) - 1;
}
else {
trackLeft = getThumbOverhang();
trackRight = getThumbOverhang() + getTrackWidth() - 1;
}
trackBottom = trackRect.height - 1;
}
if (slider.isEnabled()) {
g.setColor(MetalLookAndFeel.getControlDarkShadow());
g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1,
(trackBottom - trackTop) - 1);
g.setColor(MetalLookAndFeel.getControlHighlight());
g.drawLine(trackLeft + 1, trackBottom, trackRight, trackBottom);
g.drawLine(trackRight, trackTop + 1, trackRight, trackBottom);
g.setColor(MetalLookAndFeel.getControlShadow());
g.drawLine(trackLeft + 1, trackTop + 1,
trackRight - 2, trackTop + 1);
g.drawLine(trackLeft + 1, trackTop + 1, trackLeft + 1,
trackBottom - 2);
}
else {
g.setColor(MetalLookAndFeel.getControlShadow());
g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1,
(trackBottom - trackTop) - 1);
}
// Draw the fill
if (filledSlider) {
int middleOfThumb = 0;
int fillTop = 0;
int fillLeft = 0;
int fillBottom = 0;
int fillRight = 0;
if (slider.getOrientation() == JSlider.HORIZONTAL) {
middleOfThumb = thumbRect.x + (thumbRect.width / 2);
middleOfThumb -= trackRect.x; // To compensate for the
// g.translate()
fillTop = !slider.isEnabled() ? trackTop : trackTop + 1;
fillBottom = !slider.isEnabled() ? trackBottom - 1
: trackBottom - 2;
if (!drawInverted()) {
fillLeft = !slider.isEnabled() ? trackLeft : trackLeft + 1;
// THIS IS THE CHANGE OF NOTE:
// Fills the progress with the value from the custom slider
fillRight = xPositionForValue(((ProgressSlider) slider)
.getProgress());
fillRight -= trackRect.x;
}
else {
fillLeft = middleOfThumb;
fillRight = !slider.isEnabled() ? trackRight - 1
: trackRight - 2;
}
}
else {
middleOfThumb = thumbRect.y + (thumbRect.height / 2);
middleOfThumb -= trackRect.y; // To compensate for the
// g.translate()
fillLeft = !slider.isEnabled() ? trackLeft : trackLeft + 1;
fillRight = !slider.isEnabled() ? trackRight - 1
: trackRight - 2;
if (!drawInverted()) {
fillTop = middleOfThumb;
fillBottom = !slider.isEnabled() ? trackBottom - 1
: trackBottom - 2;
}
else {
fillTop = !slider.isEnabled() ? trackTop : trackTop + 1;
fillBottom = middleOfThumb;
}
}
if (slider.isEnabled()) {
g.setColor(slider.getBackground());
g.drawLine(fillLeft, fillTop, fillRight, fillTop);
g.drawLine(fillLeft, fillTop, fillLeft, fillBottom);
g.setColor(trackColor);
g.fillRect(fillLeft + 1, fillTop + 1, fillRight
- fillLeft, fillBottom - fillTop);
}
else {
g.setColor(MetalLookAndFeel.getControlShadow());
g.fillRect(fillLeft, fillTop, fillRight - fillLeft,
trackBottom - trackTop);
}
}
g.translate(-trackRect.x, -trackRect.y);
}
}
和用于驱动器进行测试:
public class ProgressExample extends JFrame
{
public ProgressExample()
{
super("Progress Example");
ProgressSlider mSlider = new ProgressSlider();
mSlider.setMinimum(0);
mSlider.setMaximum(100);
mSlider.setValue(20);
mSlider.setProgress(50);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(slider);
getContentPane().add(mSlider);
}
public static void main(String args[])
{
ProgressExample f = new ProgressExample();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
f.setSize(300, 80);
f.show();
}
}
其他提示
嗯,我明白你的意思。不幸的是,有没有办法做到这一点。
在“蓝条”是不是真的JSlider的一部分,它是金属LAF的一部分。它只是金属LAF选择绘制组件的方式。如果用其他LAF尝试它,你不要在酒吧所有
您将需要一个情侣JProgressBar的和JSlider的得到你想要的东西。
这里的一个起点。你需要调整它得到它看的权利。
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.event.ChangeListener;
public class ProgressSlider extends javax.swing.JPanel
{
private JProgressBar progressBar;
private JSlider slider;
public ProgressSlider() {
this(0, 100);
}
public ProgressSlider(int min, int max) {
setLayout(new GridBagLayout());
GridBagConstraints gbc;
gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
slider = new JSlider(min, max, min);
progressBar = new JProgressBar(min, max);
add(slider, gbc);
add(progressBar, gbc);
}
public void setValue(int n) {
boolean adjSlider = slider.getValue() == progressBar.getValue();
progressBar.setValue(n);
if (adjSlider)
slider.setValue(n);
}
public int getValue() {
return progressBar.getValue();
}
public int getSliderValue() {
return slider.getValue();
}
public void syncSlider() {
slider.setValue(progressBar.getValue());
}
public void addChangeListener(ChangeListener l) {
slider.addChangeListener(l);
}
public void removeChangeListener(ChangeListener l) {
slider.removeChangeListener(l);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ProgressSlider ps = new ProgressSlider();
final JTextField tf = new JTextField(4);
final JButton jb = new JButton(new AbstractAction("Set") {
public void actionPerformed(ActionEvent e) {
ps.setValue(Integer.parseInt(tf.getText()));
}});
JPanel jp = new JPanel();
jp.add(tf);
jp.add(jb);
jf.getContentPane().add(ps, BorderLayout.CENTER);
jf.getContentPane().add(jp, BorderLayout.SOUTH);
jf.pack();
jf.setVisible(true);
}
});
}
}
嗯,我看不出这是可能的。你将需要自定义UI滑块和改变模型,因为没有你需要存储的模型两条信息中,“轨道衡”和“拇指价值。”
如果你想有一个大的黑客,那么你画在彼此顶部的两个滑块。下滑动机构是为轨道值和顶部将是拇指值。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.metal.*;
public class SliderTest extends JFrame
{
public SliderTest()
{
JSlider bottom = createSlider();
bottom.setUI( new MySliderUI1() );
JSlider top = createSlider();
top.setUI( new MySliderUI2() );
top.setOpaque(false);
JPanel panel = new JPanel();
panel.setLayout( new OverlapLayout() );
panel.add( bottom );
panel.add( top );
getContentPane().add( panel );
}
private JSlider createSlider()
{
JSlider slider = new JSlider(2, 50);
slider.createStandardLabels(10, 5);
slider.setMajorTickSpacing(10);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setValue(20);
return slider;
}
class MySliderUI1 extends MetalSliderUI
{
public void paintThumb(Graphics g) {}
}
class MySliderUI2 extends MetalSliderUI
{
public void paintTrack(Graphics g) {}
}
public static void main(String[] args)
{
JFrame frame = new SliderTest();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
您还需要重叠布局。你如何保持同步是由您决定。该解决方案有许多缺陷,但它可能给你一些想法。
不隶属于 StackOverflow