Статьи

Devoxx 2008 Университетская среда


Третий день
конференции
Devoxx 2008 состоял из выступления Дэнни Кауарда и отличной беседы о параллелизме от Брайана Гетца.

 

Keynote: JavaFX: платформа для многофункциональных интернет-приложений

Дэнни Кауард,

Роберт Брюин должны были сделать ключевую запись, но, к сожалению, у него была деловая встреча. Таким образом, у всех нас есть очень разумная замена динамика, Дэнни Кауард. Он сделал достойную ключевую заметку о стратегии JavaFX. Очевидно, что маркетинговый уклон речи был направлен на то, чтобы догнать Adobe Flex и другие наивные технологии.

Что было действительно хорошо, так это то, что демонстрация FX впервые была показана перед живой аудиторией. Насколько я знаю, в этом году не было никаких взрывов, в отличие от JavaOne. Давайте не будем забывать, что европейские разработчики, большинство из которых, не имеют возможности вылететь в Калифорнию. Образцы JavaFX определенно пошатнулись, особенно когда из браузера на рабочий стол вытащен пример видео с 9-ю коробками высокого разрешения. Браузер был просто закрыт, и медиа проигрывалось без перерыва. Боже мой, я не могу сказать вам, как я был горд и как я был рад видеть клиентскую часть Java внезапно рок-н-ролл. Были слезы на моих глазах, очень немного. О, да, пример того, как поработать, если вы когда-нибудь поймаете этого умного Джоша Мариначчи, называется Video9Box.

BorderLayout Component

Ваш действительно недавно скачал JavaFX 1.0 SDK и, к его большому сожалению, обнаружил, что в комплекте больше нет компонента BorderPanel. Это было для меня головной болью, и я предполагаю, что другие разработчики чувствовали боль, портирующую код от предварительного просмотра до полного выпуска кандидата. Вот моя версия «отсутствующего» BorderLayout.

// XenonBorderPanel.fx, (c) Licence: LGPL: Peter Pilgrim, Created on 08-Dec-2008, 17:31:14

package com.xenonsoft.goliath.game.ui;

import javafx.lang.FX;
import javafx.scene.paint.Color;
import javafx.scene.Node;
import javafx.scene.Group;
import javafx.scene.layout.Container;
import javafx.scene.layout.Resizable;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.ext.swing.SwingButton;
import javafx.ext.swing.SwingComponent;
import java.lang.Math;

/**
 * A class to keep a record of the child constraints
 */
protected class ChildConstraint {
    public var prefWidth: Number = 0;
    public var prefHeight: Number = 0;
    public var resizeWidth: Number = 0;
    public var resizeHeight: Number = 0;

    override function toString(): String {
        return "[width={%7.2f width},height={%7.2f height}, resizeWidth={%7.2f resizeWidth},resizeHeight={%7.2f resizeHeight}]"
    }
}

/**
 * @author Peter Pilgrim
 */

public class XenonBorderPanel extends Container, Resizable {

    public var debug = false;

    protected function updateChildComponent( newChild:Node, oldChild: Node )
    {
        if ( newChild != oldChild ) {
            if ( oldChild != null ) {
                delete oldChild from content;
            }
            if ( newChild != null ) {
                insert newChild into content;
            }
        }
    }

    public var top: Node on replace oldValue {
        updateChildComponent(top,oldValue);
    };
    public var left: Node on replace oldValue {
        updateChildComponent(left,oldValue);
    };
    public var right: Node on replace oldValue {
        updateChildComponent(right,oldValue);
    };
    public var bottom: Node on replace oldValue {
        updateChildComponent(bottom,oldValue);
    };
    public var center: Node on replace oldValue {
        updateChildComponent(center,oldValue);
    };

    // Protected variables to this class and subclasses
    protected var leftChildConstraint: ChildConstraint;
    protected var rightChildConstraint: ChildConstraint;
    protected var topChildConstraint: ChildConstraint;
    protected var bottomChildConstraint: ChildConstraint;
    protected var centerChildConstraint: ChildConstraint;

    /** maximum preferred width of top, center and bottom children */
    protected var maxPrefWidth: Number;
    /** the maximum height of left, center and right children */
    protected var middleHeight;
    /** full width of left, center and right children summed */
    protected var fullWidth;


    public var spacing:Number on replace {
        impl_requestLayout();
    }

    init {
        impl_layout = doBorderLayout;
    }

    public function requestLayout():Void {
        impl_requestLayout();
    }

    public function getPreferredSize(node:Node): ChildConstraint {
        var constraint = ChildConstraint{ };
        if ( node != null ) {
            if ( node instanceof SwingComponent) {
                // Swing Component do not initialise the shadow FX variables min/max/prefs
                var component = (node as SwingComponent).getJComponent();
                constraint.prefWidth    = component.getPreferredSize().width;
                constraint.prefHeight   = component.getPreferredSize().height;
                constraint.resizeWidth  = constraint.prefWidth;
                constraint.resizeHeight = constraint.prefHeight;
            }
            else {
                constraint.prefWidth    = node.boundsInLocal.width;
                constraint.prefHeight   = node.boundsInLocal.height;
                constraint.resizeWidth  = constraint.prefWidth;
                constraint.resizeHeight = constraint.prefHeight;
            }
            if (debug) FX.println("getPreferredSize() ) id={node.id} constraint={constraint}");
        }
        return constraint;
    }

    public function setChildBounds( node: Node, x: Number, y: Number, constraint: ChildConstraint): Void
    {
        if (node instanceof Resizable) {
            var resizable = node as Resizable;
            resizable.width  = constraint.resizeWidth;
            resizable.height = constraint.resizeHeight;
        }
        node.impl_layoutX = x;
        node.impl_layoutY = y;
        if (debug) FX.println("setChildBounds() id={node.id} x={%7.2f x}, y={%7.2f y}, constraint={constraint}");
    }

    public function calculatePreferredSize():Void {
        leftChildConstraint   = getPreferredSize(left);
        rightChildConstraint  = getPreferredSize(right);
        topChildConstraint    = getPreferredSize(top);
        bottomChildConstraint = getPreferredSize(bottom);
        centerChildConstraint = getPreferredSize(center);

        // Compute maximum center preferred width
        maxPrefWidth = Math.max(topChildConstraint.prefWidth, centerChildConstraint.prefWidth);
        maxPrefWidth = Math.max(maxPrefWidth,bottomChildConstraint.prefWidth);
        // Computer maximum center preferred height
        middleHeight = Math.max(leftChildConstraint.prefHeight, centerChildConstraint.prefHeight);
        middleHeight = Math.max(middleHeight, rightChildConstraint.prefHeight);

        // Compute the full width of the border layout minimum requirement
        fullWidth = 2*spacing + leftChildConstraint.prefWidth + maxPrefWidth + rightChildConstraint.prefWidth;
        minimumWidth  = fullWidth;
        // Compute the minium height of the border layout
        minimumHeight = 2*spacing + topChildConstraint.prefHeight + middleHeight + bottomChildConstraint.prefHeight;
        preferredWidth  = fullWidth;
        preferredHeight = 2*spacing + topChildConstraint.prefHeight + middleHeight + bottomChildConstraint.prefHeight;
    }


    public function doBorderLayout(g:Group):Void {

        var x:Number = 0;
        var y:Number = 0;

        calculatePreferredSize();

        // calculate the real size
        if ( width > 0.0 and width > preferredWidth and center != null) {
            centerChildConstraint.resizeWidth = width - (2 * spacing + leftChildConstraint.prefWidth + rightChildConstraint.prefWidth);
            maxPrefWidth = Math.max(topChildConstraint.prefWidth, centerChildConstraint.resizeWidth);
            maxPrefWidth = Math.max(maxPrefWidth,bottomChildConstraint.prefWidth);
        }
        if ( height > 0.0 and height > preferredHeight and center != null) {
            centerChildConstraint.resizeHeight = height - (2*spacing + topChildConstraint.prefHeight + bottomChildConstraint.prefHeight);
            middleHeight = Math.max(leftChildConstraint.prefHeight, centerChildConstraint.resizeHeight);
            middleHeight = Math.max(middleHeight, rightChildConstraint.prefHeight);
        }

        fullWidth = 2*spacing + leftChildConstraint.prefWidth + maxPrefWidth + rightChildConstraint.prefWidth;

        if ( top != null ) {

            topChildConstraint.resizeWidth = fullWidth;
            setChildBounds(top, x, y, topChildConstraint);
            y += topChildConstraint.prefHeight + spacing;
        }

        x = 0;
        if ( left != null ) {
            leftChildConstraint.resizeHeight = middleHeight;
            setChildBounds(left, x, y, leftChildConstraint);
            x += leftChildConstraint.prefWidth + spacing;
        }

        if ( center != null ) {
            setChildBounds(center, x, y, centerChildConstraint);
            x += centerChildConstraint.resizeWidth + spacing;
        }

        if ( right != null ) {
            rightChildConstraint.resizeHeight = middleHeight;
            setChildBounds(right, x, y, rightChildConstraint);
            x += rightChildConstraint.prefHeight + spacing;
        }

        x = 0;
        y += middleHeight + spacing;

        if ( bottom != null ) {
            bottomChildConstraint.resizeWidth = fullWidth;
            setChildBounds(bottom, x, y, bottomChildConstraint);
        }

        if (debug) {
            FX.println("boundsInParent={boundsInParent}");
            FX.println("parent.boundsInLocal={parent.boundsInLocal}");
            FX.println("parent.boundsInParent={parent.boundsInParent}");
            FX.println("parent.boundsInScene={parent.boundsInScene}");
        }

    }

}

public function run(): Void {
    var border: XenonBorderPanel;
    var stage: Stage;
    var scene: Scene;

    stage = Stage {
        title: "Test XenonBorderPanel"
        width: 600;
        height: 800;
        onClose: function() {
            FX.exit();
        }
        scene: scene = Scene {
            content: border = XenonBorderPanel {
                width: bind scene.width
                height: bind scene.height
                top: SwingButton {
                    // foreground:  Color.AZURE
                    id: "Top"
                    text: "Top"
                    action: function(): Void {
                        FX.println("Top");
                    }
                }
                center: SwingButton {
                    id: "Center"
                    text: "Center"
                    action: function(): Void {
                        FX.println("Center");
                    }
                }
                bottom: SwingButton {
                    id: "Bottom"
                    text: "Bottom"
                    action: function(): Void {
                        FX.println("Bottom");
                    }
                }
                left: SwingButton {
                    id: "Left"
                    text: "Left"
                    action: function(): Void {
                        FX.println("Left");
                    }
                }
                right: SwingButton {
                    id: "Right"
                    text: "Right"
                    action: function(): Void {
                        FX.println("Right");
                    }
                }
            }
        }
    }
}
// The End

Я не даю никаких гарантий для его полной эксплуатации. Если у вас уже был опыт разработки пользовательских интерфейсов, например, X Windows / OSF Motif, то это должно быть действительно легко. Посмотрите мой другой блог в
четверг Devoxx для некоторых пунктов маркировки на этом BorderLayout.

От параллельного к параллельному

Брайан Гетц

Мне очень понравилась эта презентация, потому что она так четко объясняла концепцию виртуальных машин. Суть идеи Гетца заключалась в том, что мы перемещаемся с нарезанных по времени однопроцессорных машин к многоядерным процессорам, где физически возможна действительно параллельная работа. Эта презентация не имела бы никакого смысла, без диаграммы закона Мура и Гетца, объясняющих, как скорость процессора застоялась и в какой-то «чиповой» линейке фактически уменьшалась год от года, тогда как число ядер в чипе удваивается. У нас уже есть четырехъядерный процессор для настольных компьютеров, а некоторые высокопроизводительные корпоративные профили имеют стоечные системы с 768 ядрами.

Гетц утверждал, что речь идет не об одновременном использовании каждого отдельного ядра на машине для нашей программы, а о том, можем ли мы, как разработчики программного обеспечения, идти в ногу с аппаратными инновациями. Он отметил, что раньше Javac имел менее часто используемые флаги оптимизации, но поскольку JVM Sun Hotspot стала лучше оптимизировать динамический байт-код, оказалось, что компилятор может создавать плохо организованный байт-код. HotSpot реорганизует байт-код с помощью его алгоритмов адаптивного профилирования и регенерации.

Последующая часть разговора Гетца была о предложении JSR 166y, которое включает в себя новые параллельные утилиты, такие как Fork-Join. В целом это был разговор, который нельзя пропустить.

Аль Кода

Visual VM выглядит как идеальный инструмент для профилирования. Это круто!

Кричи ауты!

Джо Вориндекер , спикер и член JAVAWUG.
Фабрицио Джудичи (Fabrizio Giudici) , итальянский блогер, супремос
Алекс Бакли , рад поговорить с вами об отсутствии замыканий в JDK 7 и различных других небольших языковых изменениях.

С http://www.jroller.com/peter_pilgrim/