我正在开发一个尝试缩放通用窗口(JFrameJDialog)的应用程序。
我发现了一个问题,当要缩放JSlider组件时,即使Component本身的边界已更改,可视指针JSlider也不会缩放。
我在JSlider公共API中寻找了一个函数,该函数返回可以修改的基类Component的对象,但是我没有找到任何对象。
同样,函数jSlider1.getComponentCount()返回0。
我还查看了SliderUI类的内部,以防那里有合适的函数而没有成功。
有谁知道访问Component的可视指针JSlider的正确方法?或至少如何设置其大小以使其能够缩放?

最佳答案

正如我之前在评论中所说,我最终决定重写JSlider和MetalSliderUI类。
至少这与Java-8兼容,因为我开始的代码是oracle JDK-8之一。

下面是使用新类的示例的代码。

新介面:
ojit_pre

New overriden classes:ZoomMetalSliderUI: ojit_pre

ZoomJSlider: ojit_pre

Main class:

ojit_pre

Window class:

public interface ZoomInterface
{
    public void setZoomFactor( double zoomFactor );
    public double getZoomFactor();
}




其他班:



import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JSlider;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalSliderUI;

/**
 *
 * @author Francisco Javier Rojas Garrido <[email protected]>
 */
public class ZoomMetalSliderUI extends MetalSliderUI implements ZoomInterface
{
    protected double _zoomFactor = 1.0D;

    public ZoomMetalSliderUI()
    {
        super();
    }

    @Override
    public Dimension getThumbSize()
    {
        Dimension result = ViewFunctions.instance().getNewDimension( super.getThumbSize(), null, _zoomFactor );

        return( result );
    }

    @Override
    public void setZoomFactor(double zoomFactor)
    {
        _zoomFactor = zoomFactor;
    }

    @Override
    public double getZoomFactor()
    {
        return( _zoomFactor );
    }

    @Override
    public void paint( Graphics g, JComponent c )
    {
        calculateGeometry();
        super.paint(g, c);
    }

    @Override
    public void paintThumb(Graphics g)  {
        Rectangle knobBounds = thumbRect;

//        g.translate( knobBounds.x, knobBounds.y );

        Icon icon = null;
        if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
            icon = horizThumbIcon;
        }
        else {
            icon = vertThumbIcon;
        }

        BufferedImage bi = new BufferedImage( icon.getIconWidth(), icon.getIconHeight(),
                                                BufferedImage.TYPE_INT_ARGB );
        Graphics g1 = bi.getGraphics();

        if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
            horizThumbIcon.paintIcon( slider, bi.getGraphics(), 0, 0 );
        }
        else {
            vertThumbIcon.paintIcon( slider, bi.getGraphics(), 0, 0 );
        }

        Rectangle tr = new Rectangle( 0, 0, icon.getIconWidth(), icon.getIconHeight() );
        Rectangle newRectangle = ViewFunctions.instance().getNewRectangle(tr, null, _zoomFactor );
        BufferedImage bi_tx = ImageFunctions.resizeImage(bi, (int)newRectangle.getWidth(),
                                                        (int)newRectangle.getHeight(),
                                                        null, null, null );

        Point center = ViewFunctions.instance().getCenter(knobBounds);
        g.drawImage( bi_tx, center.x - newRectangle.width / 2,
                            center.y - newRectangle.height / 2,
                            center.x + newRectangle.width / 2,
                            center.y + newRectangle.height / 2,
                            0,
                            0,
                            bi_tx.getWidth(),
                            bi_tx.getHeight(),
                            null );
//        g.translate( -knobBounds.x, -knobBounds.y );


    }


    public void paintTrack(Graphics g)  {
/*        if (MetalLookAndFeel.usingOcean()) {
            oceanPaintTrack(g);
            return;
        }
*/
        Color trackColor = !slider.isEnabled() ? MetalLookAndFeel.getControlShadow() :
                           slider.getForeground();

//        boolean leftToRight = MetalUtils.isLeftToRight(slider);
        boolean leftToRight = isLeftToRight(slider);

        g.translate( trackRect.x, trackRect.y );

        int trackLeft = 0;
        int trackTop = 0;
        int trackRight;
        int trackBottom;

        // 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;
            int fillTop;
            int fillLeft;
            int fillBottom;
            int fillRight;

            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;
                    fillRight = middleOfThumb;
                }
                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( MetalLookAndFeel.getControlShadow() );
                g.fillRect( fillLeft + 1, fillTop + 1,
                            fillRight - fillLeft, fillBottom - fillTop );
            }
            else {
                g.setColor( MetalLookAndFeel.getControlShadow() );
                g.fillRect(fillLeft, fillTop, fillRight - fillLeft, fillBottom - fillTop);
            }
        }

        g.translate( -trackRect.x, -trackRect.y );
    }

    static boolean isLeftToRight( Component c ) {
        return c.getComponentOrientation().isLeftToRight();
    }
}






公共类IntegerFunctions
{
    公共静态int max(int i1,int i2)
    {
        return(i1> i2?i1:i2);
    }

    公共静态int min(int i1,int i2)
    {
        return(i1     }

    公共静态int abs(int ii)
    {
        return(ii> = 0?ii:-ii);
    }

    公共静态int sgn(int ii)
    {
        return(ii> 0?1:(ii     }
}






导入java.awt.Dimension;
导入java.awt.Insets;
导入java.awt.Point;
导入java.awt.Rectangle;

/ **
 *
 * @作者Usuario
 * /
公共类ViewFunctions
{
    受保护的静态ViewFunctions _instance;

    公共静态ViewFunctions instance()
    {
        if(_instance == null)
            _instance = new ViewFunctions();
        return(_instance);
    }

    public Dimension getNewDimension(Dimension dim,Insets insets,double zoomFactor)
    {
        尺寸结果= null;

        if(昏暗!= null)
        {
            if(插入== null)
                insets =新的Insets(0,0,0,0);

            int insetsWidth = insets.left + insets.right;
            int insetsHeight = insets.top + insets.bottom;
            结果=新Dimension((int)(zoomFactor *(dim.getWidth()-insetsWidth)+ insetsWidth),
                                    (int)(zoomFactor *(dim.getHeight()-insetsHeight)+ insetsHeight));
        }

        return(result);
    }

    公共Rectangle getNewRectangle(Rectangle rect,Insets insets,double zoomFactor)
    {
        矩形结果= null;

        if(rect!= null)
        {
            if(插入== null)
                insets =新的Insets(0,0,0,0);

            int insetsWidth = insets.left + insets.right;
            int insetsHeight = insets.top + insets.bottom;
            结果=新Rectangle((int)(zoomFactor *(rect.getX()+ insets.left)-insets.left),
                                        (int)(zoomFactor *(rect.getY()+ insets.top)-insets.top),
                                        (int)(zoomFactor *(rect.getWidth()-insetsWidth)+ insetsWidth),
                                        (int)(zoomFactor *(rect.getHeight()-insetsHeight)+ insetsHeight));
        }

        return(result);
    }

    公共Insets getNewInsets(Insets insets,double zoomFactor)
    {
        插入结果= null;

        if(insets!= null)
        {
            结果=新的Insets((int)(insets.top * zoomFactor),
                                    (int)(insets.left * zoomFactor),
                                    (int)(insets.bottom * zoomFactor),
                                    (int)(insets.right * zoomFactor));
        }

        return(result);
    }

    公共点getCenter(矩形rect)
    {
        点结果=空;

        if(rect!= null)
        {
            结果=新Point((int)(rect.getX()+ rect.getWidth()/ 2),
                                (int)(rect.getY()+ rect.getHeight()/ 2));
        }

        return(result);
    }

    公共Rectangle computeNewBounds(Rectangle originalBounds,Insets insets,Point center,double zoomFactor)
    {
        矩形结果= null;

        if(originalBounds!= null)
        {
            if(插入== null)
                insets =新的Insets(0,0,0,0);

            int newX =(int)originalBounds.getX();
            int newY =(int)originalBounds.getY();
            if(中心!= null)
            {
                newX =(int)(center.getX()-insets.left +(originalBounds.getX()-center.getX()+ insets.left)* zoomFactor);
                newY =(int)(center.getY()-insets.top +(originalBounds.getY()-center.getY()+ insets.top)* zoomFactor);
            }

            结果=新的Rectangle(newX,
                                    newY,
                                    (int)((ori​​ginalBounds.getWidth()-insets.left-insets.right)* zoomFactor + insets.left + insets.right),
                                    (int)((ori​​ginalBounds.getHeight()-insets.top-insets.bottom)* zoomFactor + insets.top + insets.bottom)
                                    );
        }

        return(result);
    }
}

关于java - 是否可以访问和修改JSlider的可视指针组件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48920117/

10-13 09:07