Java Source - JSlide Modify.

The following code adds color to JSlide. User may customize the color showing on JSlide. Mã nguồn sau đây thêm màu sắc cho JSlide. Người dùng có thể tùy chỉnh màu sắc hiển thị trên JSlide.
Lưu ý đoạn code này có lỗi chắc do cũ quá nên thiếu thư viện giao diện ^^! tôi chủ yếu muốn lưu lại vì có một số cách code đáng tham khảo, nên cũng không quan tâm lắm tới tính năn này nên không fix, bạn nào fix được thì share tại đây giúp nha.


MThumbSliderExample1.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MThumbSliderExample1 extends JFrame {

    public MThumbSliderExample1() {
        super("MThumbSlider Example");

        JSlider slider = new JSlider();

        int n = 2;
        MThumbSlider mSlider = new MThumbSlider(n);
        mSlider.setValueAt(25, 0);
        mSlider.setValueAt(75, 1);

        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(slider);
        getContentPane().add(mSlider);
    }

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
        } catch (Exception ex) {
            System.err.println("Error loading L&F: " + ex);
        }

        MThumbSliderExample1 f = new MThumbSliderExample1();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.setSize(300, 80);
        f.show();
    }
}


AssistantUIManager.java
import javax.swing.*;
import javax.swing.plaf.*;

public class AssistantUIManager {

    public static ComponentUI createUI(JComponent c) {
        String componentName = c.getClass().getName();

        int index = componentName.lastIndexOf(".") + 1;
        StringBuffer sb = new StringBuffer();
        sb.append(componentName.substring(0, index));



        String lookAndFeelName = UIManager.getLookAndFeel().getName();
        if (lookAndFeelName.startsWith("CDE/")) {
            lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName.length());
        }
        sb.append(lookAndFeelName);
        sb.append(componentName.substring(index));
        sb.append("UI");

        ComponentUI componentUI = getInstance(sb.toString());

        if (componentUI == null) {
            sb.setLength(0);
            sb.append(componentName.substring(0, index));
            sb.append("Basic");
            sb.append(componentName.substring(index));
            sb.append("UI");
            componentUI = getInstance(sb.toString());
        }

        return componentUI;
    }

    private static ComponentUI getInstance(String name) {
        try {
            return (ComponentUI) Class.forName(name).newInstance();
        } catch (ClassNotFoundException ex) {
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static void setUIName(JComponent c) {
        String key = c.getUIClassID();
        String uiClassName = (String) UIManager.get(key);

        if (uiClassName == null) {
            String componentName = c.getClass().getName();
            int index = componentName.lastIndexOf(".") + 1;
            StringBuffer sb = new StringBuffer();
            sb.append(componentName.substring(0, index));
            String lookAndFeelName = UIManager.getLookAndFeel().getName();
            if (lookAndFeelName.startsWith("CDE/")) {
                lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName.length());
            }
            sb.append(lookAndFeelName);
            sb.append(key);
            UIManager.put(key, sb.toString());
        }
    }

    public AssistantUIManager() {
    }
}


MThumbSlider.java
import java.awt.*;
import javax.swing.*;

public class MThumbSlider extends JSlider {

    protected int thumbNum;
    protected BoundedRangeModel[] sliderModels;
    protected Icon[] thumbRenderers;
    protected Color[] fillColors;
    protected Color trackFillColor;
    private static final String uiClassID = "MThumbSliderUI";

    public MThumbSlider(int n) {
        createThumbs(n);
        updateUI();
    }

    protected void createThumbs(int n) {
        thumbNum = n;
        sliderModels = new BoundedRangeModel[n];
        thumbRenderers = new Icon[n];
        fillColors = new Color[n];
        for (int i = 0; i < n; i++) {
            sliderModels[i] = new DefaultBoundedRangeModel(50, 0, 0, 100);
            thumbRenderers[i] = null;
            fillColors[i] = null;
        }
    }

    public void updateUI() {
        AssistantUIManager.setUIName(this);
        super.updateUI();

    }

    public String getUIClassID() {
        return uiClassID;
    }

    public int getThumbNum() {
        return thumbNum;
    }

    public int getValueAt(int index) {
        return getModelAt(index).getValue();
    }

    public void setValueAt(int n, int index) {
        getModelAt(index).setValue(n);
// should I fire?
    }

    public int getMinimum() {
        return getModelAt(0).getMinimum();
    }

    public int getMaximum() {
        return getModelAt(0).getMaximum();
    }

    public BoundedRangeModel getModelAt(int index) {
        return sliderModels[index];
    }

    public Icon getThumbRendererAt(int index) {
        return thumbRenderers[index];
    }

    public void setThumbRendererAt(Icon icon, int index) {
        thumbRenderers[index] = icon;
    }

    public Color getFillColorAt(int index) {
        return fillColors[index];
    }

    public void setFillColorAt(Color color, int index) {
        fillColors[index] = color;
    }

    public Color getTrackFillColor() {
        return trackFillColor;
    }

    public void setTrackFillColor(Color color) {
        trackFillColor = color;
    }
}


MThumbSliderAdditional.java
import java.awt.*;

public interface MThumbSliderAdditional {

    public Rectangle getTrackRect();

    public Dimension getThumbSize();

    public int xPositionForValue(int value);

    public int yPositionForValue(int value);
}


MThumbSliderAdditionalUI.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;

public class MThumbSliderAdditionalUI {

    MThumbSlider mSlider;
    BasicSliderUI ui;
    Rectangle[] thumbRects;
    int thumbNum;
    private transient boolean isDragging;
    Icon thumbRenderer;
    Rectangle trackRect;
    ChangeHandler changeHandler;
    TrackListener trackListener;

    public MThumbSliderAdditionalUI(BasicSliderUI ui) {
        this.ui = ui;
    }

    public void installUI(JComponent c) {
        mSlider = (MThumbSlider) c;
        thumbNum = mSlider.getThumbNum();
        thumbRects = new Rectangle[thumbNum];
        for (int i = 0; i < thumbNum; i++) {
            thumbRects[i] = new Rectangle();
        }
        isDragging = false;
        trackListener = new MThumbSliderAdditionalUI.TrackListener(mSlider);
        changeHandler = new ChangeHandler();
    }

    public void uninstallUI(JComponent c) {
        thumbRects = null;
        trackListener = null;
        changeHandler = null;
    }

    protected void calculateThumbsSize() {
        Dimension size = ((MThumbSliderAdditional) ui).getThumbSize();
        for (int i = 0; i < thumbNum; i++) {
            thumbRects[i].setSize(size.width, size.height);
        }
    }

    protected void calculateThumbsLocation() {
        for (int i = 0; i < thumbNum; i++) {
            if (mSlider.getSnapToTicks()) {
                int tickSpacing = mSlider.getMinorTickSpacing();
                if (tickSpacing == 0) {
                    tickSpacing = mSlider.getMajorTickSpacing();
                }
                if (tickSpacing != 0) {
                    int sliderValue = mSlider.getValueAt(i);
                    int snappedValue = sliderValue;
                    //int min = mSlider.getMinimumAt(i);
                    int min = mSlider.getMinimum();
                    if ((sliderValue - min) % tickSpacing != 0) {
                        float temp = (float) (sliderValue - min) / (float) tickSpacing;
                        int whichTick = Math.round(temp);
                        snappedValue = min + (whichTick * tickSpacing);
                        mSlider.setValueAt(snappedValue, i);
                    }
                }
            }
            trackRect = getTrackRect();
            if (mSlider.getOrientation() == JSlider.HORIZONTAL) {
                int value = mSlider.getValueAt(i);
                int valuePosition = ((MThumbSliderAdditional) ui).xPositionForValue(value);
                thumbRects[i].x = valuePosition - (thumbRects[i].width / 2);
                thumbRects[i].y = trackRect.y;

            } else {
                int valuePosition = ((MThumbSliderAdditional) ui).yPositionForValue(mSlider.getValueAt(i)); // need
                thumbRects[i].x = trackRect.x;
                thumbRects[i].y = valuePosition - (thumbRects[i].height / 2);
            }
        }
    }

    public int getThumbNum() {
        return thumbNum;
    }

    public Rectangle[] getThumbRects() {
        return thumbRects;
    }
    private static Rectangle unionRect = new Rectangle();

    public void setThumbLocationAt(int x, int y, int index) {
        Rectangle rect = thumbRects[index];
        unionRect.setBounds(rect);

        rect.setLocation(x, y);
        SwingUtilities.computeUnion(rect.x, rect.y, rect.width, rect.height, unionRect);
        mSlider.repaint(unionRect.x, unionRect.y, unionRect.width, unionRect.height);
    }

    public Rectangle getTrackRect() {
        return ((MThumbSliderAdditional) ui).getTrackRect();
    }

    public class ChangeHandler implements ChangeListener {

        public void stateChanged(ChangeEvent e) {
            if (!isDragging) {
                calculateThumbsLocation();
                mSlider.repaint();
            }
        }
    }

    public class TrackListener extends MouseInputAdapter {

        protected transient int offset;
        protected transient int currentMouseX, currentMouseY;
        protected Rectangle adjustingThumbRect = null;
        protected int adjustingThumbIndex;
        protected MThumbSlider slider;
        protected Rectangle trackRect;

        TrackListener(MThumbSlider slider) {
            this.slider = slider;
        }

        public void mousePressed(MouseEvent e) {
            if (!slider.isEnabled()) {
                return;
            }
            currentMouseX = e.getX();
            currentMouseY = e.getY();
            slider.requestFocus();

            for (int i = 0; i < thumbNum; i++) {
                Rectangle rect = thumbRects[i];
                if (rect.contains(currentMouseX, currentMouseY)) {

                    switch (slider.getOrientation()) {
                        case JSlider.VERTICAL:
                            offset = currentMouseY - rect.y;
                            break;
                        case JSlider.HORIZONTAL:
                            offset = currentMouseX - rect.x;
                            break;
                    }
                    isDragging = true;
                    slider.setValueIsAdjusting(true);
                    adjustingThumbRect = rect;
                    adjustingThumbIndex = i;
                    return;
                }
            }
        }

        public void mouseDragged(MouseEvent e) {
            if (!slider.isEnabled()
                    || !isDragging
                    || !slider.getValueIsAdjusting()
                    || adjustingThumbRect == null) {
                return;
            }
            int thumbMiddle = 0;
            currentMouseX = e.getX();
            currentMouseY = e.getY();

            Rectangle rect = thumbRects[adjustingThumbIndex];
            trackRect = getTrackRect();
            switch (slider.getOrientation()) {
                case JSlider.VERTICAL:
                    int halfThumbHeight = rect.height / 2;
                    int thumbTop = e.getY() - offset;
                    int trackTop = trackRect.y;
                    int trackBottom = trackRect.y + (trackRect.height - 1);

                    thumbTop = Math.max(thumbTop, trackTop - halfThumbHeight);
                    thumbTop = Math.min(thumbTop, trackBottom - halfThumbHeight);

                    setThumbLocationAt(rect.x, thumbTop, adjustingThumbIndex);

                    thumbMiddle = thumbTop + halfThumbHeight;
                    mSlider.setValueAt(ui.valueForYPosition(thumbMiddle), adjustingThumbIndex);
                    break;

                case JSlider.HORIZONTAL:
                    int halfThumbWidth = rect.width / 2;
                    int thumbLeft = e.getX() - offset;
                    int trackLeft = trackRect.x;
                    int trackRight = trackRect.x + (trackRect.width - 1);

                    thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
                    thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);

                    setThumbLocationAt(thumbLeft, rect.y, adjustingThumbIndex);

                    thumbMiddle = thumbLeft + halfThumbWidth;
                    mSlider.setValueAt(ui.valueForXPosition(thumbMiddle), adjustingThumbIndex);
                    break;
            }
        }

        public void mouseReleased(MouseEvent e) {
            if (!slider.isEnabled()) {
                return;
            }
            offset = 0;
            isDragging = false;
            mSlider.setValueIsAdjusting(false);
            mSlider.repaint();
        }

        public boolean shouldScroll(int direction) {
            return false;
        }
    }
}


MetalMThumbSliderUI.java
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.metal.*;

public class MetalMThumbSliderUI extends MetalSliderUI
        implements MThumbSliderAdditional {

    MThumbSliderAdditionalUI additonalUi;
    MouseInputAdapter mThumbTrackListener;

    public static ComponentUI createUI(JComponent c) {
        return new MetalMThumbSliderUI((JSlider) c);
    }

    public MetalMThumbSliderUI() {
//super(null);
    }

    public MetalMThumbSliderUI(JSlider b) {
//super(null);
    }

    public void installUI(JComponent c) {
        additonalUi = new MThumbSliderAdditionalUI(this);
        additonalUi.installUI(c);
        mThumbTrackListener = createMThumbTrackListener((JSlider) c);
        super.installUI(c);
    }

    public void uninstallUI(JComponent c) {
        super.uninstallUI(c);
        additonalUi.uninstallUI(c);
        additonalUi = null;
        mThumbTrackListener = null;
    }

    protected MouseInputAdapter createMThumbTrackListener(JSlider slider) {
        return additonalUi.trackListener;
    }

    protected TrackListener createTrackListener(JSlider slider) {
        return null;
    }

    protected ChangeListener createChangeListener(JSlider slider) {
        return additonalUi.changeHandler;
    }

    protected void installListeners(JSlider slider) {
        slider.addMouseListener(mThumbTrackListener);
        slider.addMouseMotionListener(mThumbTrackListener);
        slider.addFocusListener(focusListener);
        slider.addComponentListener(componentListener);
        slider.addPropertyChangeListener(propertyChangeListener);
        slider.getModel().addChangeListener(changeListener);
    }

    protected void uninstallListeners(JSlider slider) {
        slider.removeMouseListener(mThumbTrackListener);
        slider.removeMouseMotionListener(mThumbTrackListener);
        slider.removeFocusListener(focusListener);
        slider.removeComponentListener(componentListener);
        slider.removePropertyChangeListener(propertyChangeListener);
        slider.getModel().removeChangeListener(changeListener);
    }

    protected void calculateGeometry() {
        super.calculateGeometry();
        additonalUi.calculateThumbsSize();
        additonalUi.calculateThumbsLocation();
    }

    protected void calculateThumbLocation() {
    }
    Icon thumbRenderer;

    public void paint(Graphics g, JComponent c) {
        Rectangle clip = g.getClipBounds();
        Rectangle[] thumbRects = additonalUi.getThumbRects();
        thumbRect = thumbRects[0];
        int thumbNum = additonalUi.getThumbNum();

        if (slider.getPaintTrack() && clip.intersects(trackRect)) {
            boolean filledSlider_tmp = filledSlider;
            filledSlider = false;
            paintTrack(g);
            filledSlider = filledSlider_tmp;

            if (filledSlider) {
                g.translate(trackRect.x, trackRect.y);

                Point t1 = new Point(0, 0);
                Point t2 = new Point(0, 0);
                Rectangle maxThumbRect = new Rectangle(thumbRect);
                thumbRect = maxThumbRect;

                if (slider.getOrientation() == JSlider.HORIZONTAL) {
                    t2.y = (trackRect.height - 1) - getThumbOverhang();
                    t1.y = t2.y - (getTrackWidth() - 1);
                    t2.x = trackRect.width - 1;
                    int maxPosition = xPositionForValue(slider.getMaximum());
                    thumbRect.x = maxPosition - (thumbRect.width / 2) - 2;
                    thumbRect.y = trackRect.y;
                } else {
                    t1.x = (trackRect.width - getThumbOverhang()) - getTrackWidth();
                    t2.x = (trackRect.width - getThumbOverhang()) - 1;
                    t2.y = trackRect.height - 1;
                    int maxPosition = yPositionForValue(slider.getMaximum());
                    thumbRect.x = trackRect.x;
                    thumbRect.y = maxPosition - (thumbRect.height / 2) - 2;
                }

                Color fillColor = ((MThumbSlider) slider).getTrackFillColor();
                if (fillColor == null) {
                    fillColor = MetalLookAndFeel.getControlShadow();
                }
                fillTrack(g, t1, t2, fillColor);

                for (int i = thumbNum - 1; 0 <= i; i--) {
                    thumbRect = thumbRects[i];
                    fillColor = ((MThumbSlider) slider).getFillColorAt(i);
                    if (fillColor == null) {
                        fillColor = MetalLookAndFeel.getControlShadow();
                    }
                    fillTrack(g, t1, t2, fillColor);
                }

                g.translate(-trackRect.x, -trackRect.y);
            }
        }
        if (slider.getPaintTicks() && clip.intersects(tickRect)) {
            paintTicks(g);
        }
        if (slider.getPaintLabels() && clip.intersects(labelRect)) {
            paintLabels(g);
        }

        for (int i = thumbNum - 1; 0 <= i; i--) {
            if (clip.intersects(thumbRects[i])) {
                thumbRect = thumbRects[i];
                thumbRenderer = ((MThumbSlider) slider).getThumbRendererAt(i);
                if (thumbRenderer == null) {
                    if (slider.getOrientation() == JSlider.HORIZONTAL) {
                        thumbRenderer = horizThumbIcon;
                    } else {
                        thumbRenderer = vertThumbIcon;
                    }
                }
                paintThumb(g);
            }
        }
    }

    public void paintThumb(Graphics g) {
        thumbRenderer.paintIcon(slider, g, thumbRect.x, thumbRect.y);
    }

    public void fillTrack(Graphics g, Point t1, Point t2, Color fillColor) {
// t1-------------------
// | |
// --------------------t2
        int middleOfThumb = 0;

        if (slider.getOrientation() == JSlider.HORIZONTAL) {
            middleOfThumb = thumbRect.x + (thumbRect.width / 2) - trackRect.x;
            if (slider.isEnabled()) {
                g.setColor(fillColor);
                g.fillRect(t1.x + 2,
                        t1.y + 2,
                        middleOfThumb - t1.x - 1,
                        t2.y - t1.y - 3);
                g.setColor(fillColor.brighter());
                g.drawLine(t1.x + 1, t1.y + 1, middleOfThumb, t1.y + 1);
                g.drawLine(t1.x + 1, t1.y + 1, t1.x + 1, t2.y - 2);
            } else {
                g.setColor(fillColor);
                g.fillRect(t1.x,
                        t1.y,
                        middleOfThumb - t1.x + 2,
                        t2.y - t1.y);
            }
        } else {
            middleOfThumb = thumbRect.y + (thumbRect.height / 2) - trackRect.y;
            if (slider.isEnabled()) {
                g.setColor(slider.getBackground());
                g.drawLine(t1.x + 1, middleOfThumb, t2.x - 2, middleOfThumb);
                g.drawLine(t1.x + 1, middleOfThumb, t1.x + 1, t2.y - 2);
                g.setColor(fillColor);
                g.fillRect(t1.x + 2,
                        middleOfThumb + 1,
                        t2.x - t1.x - 3,
                        t2.y - 2 - middleOfThumb);
            } else {
                g.setColor(fillColor);
                g.fillRect(t1.x,
                        middleOfThumb + 2,
                        t2.x - 1 - t1.x,
                        t2.y - t1.y);
            }
        }
    }

    public void scrollByBlock(int direction) {
    }

    public void scrollByUnit(int direction) {
    }

//
// MThumbSliderAdditional
//
    public Rectangle getTrackRect() {
        return trackRect;
    }

    public Dimension getThumbSize() {
        return super.getThumbSize();
    }

    public int xPositionForValue(int value) {
        return super.xPositionForValue(value);
    }

    public int yPositionForValue(int value) {
        return super.yPositionForValue(value);
    }
}


Kết quả - Result








No comments:

Post a Comment