JDK-4749723 : The javax.swing.Spring class needs a "scale" operator to make centering easier.
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-09-18
  • Updated: 2017-05-16
  • Resolved: 2003-08-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
Other
5.0 tigerFixed
Description

Name: rmT116609			Date: 09/18/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

also:

java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)



DESCRIPTION OF THE PROBLEM :
Centering multiple components with a SpringLayout requires a subclass of Spring which can divide the atrributes of a Spring in half. A "scale" operator
can perform this function and would fit well with the "sum", " minus" and "max" operators the class already provides.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. javac TestCenter2.java
2. java TestCenter2

EXPECTED VERSUS ACTUAL BEHAVIOR :
The provided source shows one way to center components
with a SpringLayout. This is an RFE, so no error is
produced.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

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

public class TestCenter2 {
    public static class ScaleSpring extends Spring {
        private Spring s;
        private double factor;

        private ScaleSpring(Spring s, double factor) {
            this.s = s;
            this.factor = factor;
        }

        public int getMinimumValue() {
            return (int)((factor < 0 ? s.getMaximumValue() : s.getMinimumValue
()) * factor);
        }

        public int getPreferredValue() {
            return (int)(s.getPreferredValue() * factor);
        }

        public int getMaximumValue() {
            return (int)((factor < 0 ? s.getMinimumValue() : s.getMaximumValue
()) * factor);
        }

        public int getValue() {
            return (int)(s.getValue() * factor);
        }

        public void setValue(int value) {
            s.setValue((int)(value / factor));
        }
    }

    public static Spring scale(Spring s, double factor) {
        return new ScaleSpring(s, factor);
    }

    public static void main(String[] args) {
        JFrame f = new JFrame();
        Container p = f.getContentPane();

        JComponent c1 = new JTextField("Spectacular");
        JComponent c2 = new JTextField("Bar");

//        JComponent c1 = new JButton("Foo");
//        c1.setMinimumSize(new Dimension(0, 0));
//        c1.setMaximumSize(new Dimension(Integer.MAX_VALUE,
Integer.MAX_VALUE));
//        JComponent c2 = new JButton("Bar");
//        c1.setMinimumSize(new Dimension(0, 0));
//        c1.setMaximumSize(new Dimension(Integer.MAX_VALUE,
Integer.MAX_VALUE));

        SpringLayout l = new SpringLayout();
        p.setLayout(l);

        p.add(c1);
        p.add(c2);

        SpringLayout.Constraints pc = l.getConstraints(p);
        SpringLayout.Constraints bc1 = l.getConstraints(c1);
        SpringLayout.Constraints bc2 = l.getConstraints(c2);

        Spring middle = scale(pc.getWidth(), 0.5);

        bc1.setX(Spring.sum(middle, Spring.minus(scale(bc1.getWidth(), 0.5))));
        bc2.setX(Spring.sum(middle, Spring.minus(scale(bc2.getWidth(), 0.5))));
        pc.setConstraint("East", Spring.constant(0, 300, 1000));
//        pc.setConstraint("East", Spring.max(bc1.getWidth(), bc2.getWidth()));

        bc1.setY(Spring.constant(0, 10, 100));
        bc2.setY(Spring.sum(Spring.constant(10), bc1.getConstraint("South")));
        pc.setConstraint("South", Spring.sum(Spring.constant(10),
bc2.getConstraint("South")));

        f.pack();
        f.setVisible(true);
    }
}

---------- END SOURCE ----------
(Review ID: 164663) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b16
2004-06-14

EVALUATION We ended up adding: /** * Returns a spring whose <em>minimum</em>, <em>preferred</em>, <em>maximum</em> * and <em>value</em> properties are each multiples of the properties of the * argument spring, <code>s</code>. Minimum and maximum properties are * swapped when <code>factor</code> is negative (in accordance with the * rules of interval arithmetic). * <p> * When factor is, for example, 0.5f the result represents 'the mid-point' * of its input - an operation that is useful for centering components in * a container. * * @param s the spring to scale * @param factor amount to scale by. * @return a spring whose properties are those of the input spring <code>s</code> * multiplied by <code>factor</code> * @throws NullPointerException if <code>s</code> is null * @since 1.5 */ public static Spring scale(Spring s, float factor); /** * Returns a spring whose <em>minimum</em>, <em>preferred</em>, <em>maximum</em> * and <em>value</em> properties are defined by the widths of the <em>minimumSize</em>, * <em>preferredSize</em>, <em>maximumSize</em> and <em>size</em> properties * of the supplied component. The returned spring is a 'wrapper' implementation * whose methods call the appropriate size methods of the supplied component. * The minimum, preferred, maximum and value properties of the returned spring * therefore report the current state of the appropriate properties in the * component and track them as they change. * * @param c Component used for calculating size * @return a spring whose properties are defined by the horizontal component * of the component's size methods. * @throws NullPointerException if <code>c</code> is null * @since 1.5 */ public static Spring width(Component c); /** * Returns a spring whose <em>minimum</em>, <em>preferred</em>, <em>maximum</em> * and <em>value</em> properties are defined by the heights of the <em>minimumSize</em>, * <em>preferredSize</em>, <em>maximumSize</em> and <em>size</em> properties * of the supplied component. The returned spring is a 'wrapper' implementation * whose methods call the appropriate size methods of the supplied component. * The minimum, preferred, maximum and value properties of the returned spring * therefore report the current state of the appropriate properties in the * component and track them as they change. * * @param c Component used for calculating size * @return a spring whose properties are defined by the vertical component * of the component's size methods. * @throws NullPointerException if <code>c</code> is null * @since 1.5 */ public static Spring height(Component c); /** * Creates a <code>Constraints</code> object with * suitable <code>x</code>, <code>y</code>, <code>width</code> and * <code>height</code> springs for component, <code>c</code>. * The <code>x</code> and <code>y</code> springs are constant * springs initialised with the component's location at * the time this method is called. The <code>width</code> and * <code>height</code> springs are special springs, created by * the <code>Spring.width()</code> and <code>Spring.height()</code> * methods, which track the size characteristics of the component * when they change. * * @param c the component whose characteristics will be reflected by this Constraints object * @throws NullPointerException if <code>c</code> is null. * @since 1.5 */ public Constraints(Component c); ###@###.### 2003-08-05
2003-08-05