к оглавлению   к 4GL - визуальному программированию

Программирование Dynamic HTML в Java

В состав обозревателя Internet Explorer 4.0 фирма Microsoft включила свою реализацию современной модели объектов HTML, позволяющую эффективно управлять свойствами HTML «на лету». До сих пор к этой модели объектов обращались в основном посредством сценариев. Теперь же пакет com-.ms.wfc.html из WFC (Windows Foundation Classes for Java) открывает доступ ко всей мощи Dynamic HTML (DHTML) на Web-странице напрямую из Java-класса. Из этой главы Вы узнаете, как:

Быстрый старт

Здесь описаны основные этапы создания простого проекта DHTML и его настройки — изучив их, Вы в общих чертах узнаете, как использовать пакет com.ms.wfc.html для работы с Java и DHTML. Вот эти пять основных этапов.

  1. Создайте новый проект, выбрав команду New Project из меню File и затем выделив Code-behind HTML в категории Web Pages. Сгенерируется проект с классом Classl, который является расширением класса DhDocument и представляет собой динамический HTML-документ. Для управления «содержанием» и поведением документа в его метод initForm добавляется код инициализации.

    Теперь Вы можете расширить возможности документа следующим образом.

  2. Создайте новые элементы (например, DhButton) или создайте объекты-элементы, которые представляют элементы, имеющиеся в документе (на HTML-странице).
  3. Вставьте обработчики событий в некоторые из Ваших элементов.
  4. В методе Classl.initForm добавьте новые элементы с помощью метода setNewElements и свяжите все имеющиеся элементы, пользуясь методом setBoundElements.
  5. Напишите методы обработчиков событий, вставленных Вами на этапе 3.

Ваш класс документа будет выглядеть примерно так: import com.ms.wfc.html.*; import com.ms.wfc.core. *; import com.ms.wfc.ui. *;

public class Classl extends DhDocument {

public Classl()

{

initForm();

}

// Этап 2: создать объекты для представления новых элементов...

DhButton newElem = new DhButtonO;

// ... и элементов, имеющихся на HTML-странице.

DhText existElem = new DhText();

private void initForm( )

{

// Установить свойства имеющихся и заново добавленных элементов.

newElem.setText("hello world");

existElem.setBackColor(Color. BLUE);

// Этап З: добавить в объект обработчик события

newElem.addOnClick(new EventHandler(this.onClickButton));

// Этап 2: создать объект, представляющий собой имеющийся элемент existElem = new DhTextO;

// Этап 4: вызвать setNewElements с массивом новых элементов setNewElements(new Component[] { newElem });

// Этап 4: вызвать setBoundElements с массивом имеющихся элементов

setBoundElements(new DhElenent[]{ existElem.setBindID("Sample") }); }

// Этап 5: реализовать обработчик события

private void onClickButton(Object sender, Event e) { existElem.setText("Hello, world");

} }

Этим заканчивается фрагмент примера, относящийся к Java. Другую его часть составляет HTML-код. Ниже показана упрощенная версия документа HTML, генерируемая шаблоном проекта Code-behind HTML. Два элемента HTML соединяют этот код с кодом проекта на Java.

<HTML> <BODY> <OBJECT classid="Java:com.ms.wfс.html.DhModule"height=0 width=0 ... VIEWASTEXT>

<PARAM NAME=CABBASE VALUE=MyProject>

<PARAM NAME=CODECLASS VALUE=Class1>

</OBJECT>

<span id=Sample></span>

<!—Вставьте здесь Ваш HTML-код — >

</BODY> </HTML>

Запустите Internet Explorer 4.0, загрузите в него HTML-файл и наблюдайте приложение в действии.

Использование метода initForm

Метод initForm играет центральную роль в модели программирования для всех пользовательских интерфейсов в WFC. При использовании Visual J++ Forms Designer для приложений на основе Win32 метод initForm хранится в классе, производном от Form и представляющем ' собой основную форму. В пакете com.ms.wfc.html этот метод находится в классе, производном от DhDocument (например, Classl в шаблоне Code-Behind HTML, поставляемом с Visual J+ + ), и вызывается из конструктора класса.

Метод initForm следует использовать для инициализации компонентов Java, представляющих собой элементы HTML, к которым нужно иметь доступ. Как и для метода initForm в классах, производных от Form, есть определенные ограничения и при вызове WFC-методов из initForm в DhDocument. Обычно в initForm надо вызывать только методы, устанавливающие свойства. Более того, следует связываться с элементами на HTML-странице, пользуясь только методом setBoundElements. Конкретно это означает, что в initForm не поддерживается вызов какою-либо метода, который переустанавливает или удаляет свойство или элемент. Это относится и к любому методу, который пытается найти элемент на существующей HTML-странице (например, DhDocument.findElement). Причина в том, что документ на имеющейся HTML-странице не соединяется с классом, производным от DhDocument, до тех пор, пока не будет вызван метод DhDocument.onDocumentLoad. Можно использовать метод onDocumentLoad для получения значений свойств элементов, управления ими и нахождения их в существующих документах HTML. Информация об использовании методов initForm и onDocumentLoad в классах на стороне сервера приведена далее в этой главе в разделе «Использование пакета com.ms.wfc.html на сервере».

Описание класса DhElement

Элементы — это объекты, производные от класса DhElement, который является суперклассом всех элементов пользовательского интерфейса в пакете com.ms.wfc.html. Ниже перечислены правила работы с любым объектом, производным от DhElement.

Если элемент уже находится на странице в момент вызова метода DhDocument.onDocumentLoad, можно вызвать метод документа findElement и начать программирование этого элемента. Вы вправе также вызвать setBoundElements изнутри initForm, чтобы соединить известные элементы на странице с элементами в классе, производном от DhDocument. (Метод findElement имеет лучшую производительность, но явно требует, чтобы сначала был вызван onDocumentLoad.) Механизм поиска, используемый findElement и setBoundElements, предполагает, что элемент, который надо связывать, имеет идентификационный атрибут, настроенный на конкретное имя. Используя findElement, можно перебирать все элементы в документе до тех пор, пока не будет найден нужный1.

Работа с контейнерами

Контейнеры — это элементы, которые могут хранить другие элементы. Типовым примером является элемент <DIV>, содержащий любой другой элемент HTML. Более сложные примеры — это ячейки таблицы и, конечно, сам, документ. В большинстве случаев допускается произвольное вложение контейнеров. Например, таблица, которая хранится внутри ячейки другой таблицы.

Контейнеры подобны другим элементам. Они создаются посредством оператора new, и для многих из них могут быть изменены размер и положение на странице. Вы вправе позиционировать элементы и корректировать их размеры внутри контейнера, редактировать их элементы и определять их z-порядок. Одна из сильных сторон DHTML — возможность изменения любого из этих атрибутов в Вашем коде. Разумеется, элементы в контейнере могут размещаться по обычным правилам раскладки HTML. Для этого вызовите либо методы элемента setLocation или setBound для задания его абсолютной позиции, либо resetLocation, чтобы позицию элемента определил механизм позиционирования HTML (сразу после добавления последнего элемента в HTML). Создав контейнерный элемент, Вы вправе добавлять в него элементы методами setNewElements или add. Этот механизм следует обычному правилу родительско-дочерних взаимоотношений: элементы (которые сами могут быть контейнерами), добавленные в контейнер, становятся дочерними. В действительности ничто не присоединяется к документу до тех пор, пока самый верхний в иерархии контейнер, не являющийся частью другого контейнера, не будет добавлен в документ. Задать положение и размер контейнера можно, используя метод setBounds.

Например, чтобы создать контейнер, напишите:

DhForm myForm = new DhForm();

Затем задайте разные атрибуты контейнера, включая ToolTip (подсказку) — она появляется при движении указателя мыши над формой:

myForm.setToolTip("This text appears when the mouse hovers");

myForm.setFont("Arial", 10);

myForm.setBackColor(Color.RED);

myForm.setBounds(5, 5, 100, 100);

Наконец, добавьте только что созданный контейнер в документ в классе, производном от DhDocument (например, Classl.java):

this.add(myForm);

При добавлении элементов в контейнер можно задать их z-порядок, используя один из наборов констант из пакета com.ms.wfc.html. Элементы добавляются с использованием позиций и размеров по умолчанию. Для изменения размера элемента вызовите setBounds.

DhForm myOverLayl = new DhForm();

DhForm myOverl_ay2 = new DhForm();

myOverLayl.setBackColor(Color.BLACK);

myOverLayl.setBounds(10, 10, 50, 50);

myOverLay2.setBackColor(Color.BLUE);

myOverLay2.setBounds(20,25, 50, 50);

myForm.add(myOverLay1, null, DhlnsertOptions.BEGINNING);

// Черное поверх синего

myForm.add(myOverLay2, myOverLayl, DhlnsertOptions.BEFORE);

// Синее поверх черного (раскомментируйте следующую строку и закомментируйте

// предыдущую)

myForm.add(myOverLay2, myOverLayl, DhlnsertOptions.AFTER);

Для изменения z-порядка элементов после их добавления используйте метод setZIndex. Например, следующий оператор не задает явно z-порядок добавляемого элемента, а использует z-порядок по умолчанию (т. е. поверх всех остальных элементов):

myForm.add(myText);

Можно явно задать z-порядок следующим образом( num — это целое, представляющее собой относительный z-порядок элемента внутри контейнера):

myText.setZIndex(num);

Элемент с наименьшим номером находится внизу в z-порядке (т. е. все другие перекрывают его). Элемент с наибольшим номером находится сверху (т. е. он перекрывает все остальные).

Обработка событий

Многие элементы в программе DHTML могут генерировать события. Пакет com.ms.wfc.html использует ту же модель событий, что и пакет com.ms.wfc.ui. Если Вы знакомы с его механизмом, то найдете небольшие различия между ними. Возьмем, к примеру, кнопку. Предположим, Вы хотите обработать событие, которое происходит, когда пользователь щелкает кнопку на странице: public class Class1 extends DhDocument {

Class1() { initForm();}

DnButton myButton = new DhButton();

private void initForm()

{

add(myButton);

myButton.addOnClick(new EventHandler(this.myButtonClick));

}

void myButtonClick(Ob]ect sender, Event e)

{

((DhButton) sender).setText("I've been clicked");

} }

В этом коде при каждой генерации события onClick кнопкой (т. е. ког да кнопку щелкнули) вызывается обработчик события myButtonClick Здесь код внутри обработчика события myButtonClick делает очен мало — всего лишь устанавливает новый текст на кнопке. Большинство событий распространяется по всему дереву контейнере (containment tree); это означает, что событие-щелчок видно и в контей нере кнопки, и в самой кнопке. Хотя обычно программисты обрабаты вают события в контейнере, ближайшем к источнику события, така. модель «всплытия» событий (event bubbling) иногда весьма полезна. Он: позволяет программисту гибко выбирать лучшее место для обработк] события.

Элементы в DHTML способны сгенерировать много разных событий, ] все их можно перехватить одним и тем же способом. Например, чтоб! определить, когда указатель мыши находится поверх кнопки, попробуй те использовать следующий код (он перехватывает события от кнопк] mouseEnter и mouseLeave):

public class Classl extends DhDocument {

DhButton button = new DhButton();

private void initForm()

{

button.addOnMouseEnter(new MouseEventHandler(this.buttonEnter));

button.addOnrfouseLeave(new MouseEventHandler(this.buttonExit);

setNewElements( new DhElement[] { button } );

}

void buttonEnter(Object sender, MouseEvent e)

{

button.setText("I can feel that mouse");

}

void buttonExit(Ob]ect sender, MouseEvent e)

{

button.setText("button");

}

}

Все события, которые могут быть сгенерированы (и перехвачены), определены в классах событий, основанных на com.ms.wfc.core.Event.

Использование динамических стилей

Объект Style можно представить себе как произвольный набор свойств. Термин «стиль» взят из текстовых редакторов, где корректировка таблицы стилей не зависит от документов, к которым она относится. Это касается и использования объектов Style в этой библиотеке. Например, руководство компании объявило новый цвет корпорации — красный, и поэтому Вам приходится менять цвет элементов на HTML-страницах. Вы вправе, конечно, установить свойства элементов напрямую, что традиционно для программирования графического интерфейса: // старый способ ведения дел... DhText t1 = new DhText(); DhText t2 = new DhText(); t1.setColor( Color.RED ); t1.setFont( "arial"); t2.setColor( Color.RED ); t2.setFont( "arial");

Для экономии времени можно воспользоваться производной от этого решения:

// старый, но улучшенный способ ведения дел...

public class MyText extends DhText

{

public MyText() {

setColor( Color.RED ); setFont( "arial" ); }

Все это хорошо, пока Вы не пожелаете таким же образом настроить кнопки, метки, вкладки, документы и т. д. И здесь обнаружится, что на это требуется больше времени, чем на любую другую часть программы или иную программу.

Решение проблемы — объект Style. При использовании этой библиотеки Вы сумеете в любой момент создать объект Style и установить его свойства:

// ШАГ 1: Создать объект. DhStyle myStyle = new DhStyle(); // ШАГ 2: Задать его свойства

myStyle.setColor( Color.RED ); myStyle.setFont( "arial" );

Затем когда угодно Вы сможете применить этот стиль в коде к произвольному числу элементов:

DhText t1 = new DhText();

DhText t2 = new DhText();

// ШАГ З: Применить стиль, используя метод setStyle.

t1.setStyle( myStyle );

t2.setStyle( myStyle );

И теперь Вы без труда реализуете все решения руководства корпорации об изменении цветов — одна строка позволит Вам изменить цвет всех экземпляров любого элемента, использующего myStyle:

myStyle.setColor( Color.BLUE );

Но самое главное: все это возможно во время выполнения. Каждый раз, когда Вы вносите изменения в объект Style, библиотека DHTML времени выполнения динамически обновляет все элементы, к которым применен объект Style.

Дополнительную информацию см. в следующем разделе «Подробности наследования стилей».

Подробности наследования стилей

Механизм отрисовки HTML определяет подлежащий применению стиль, если для элемента заданы конфликтующие стили. Например, если элемент имеет свойство цвета, установленное напрямую (DhElement.setColor), то используется цвет на его основе. Однако если у элемента есть объект Style (DhElement.setStyle), для которого установлено свойство цвета, то используется его значение. Если не найдены цвет и стиль, то тот же процесс применяется для контейнера элемента (DhElement.getParent), затем для контейнера этого контейнера и т. д. Процесс продолжается до самого документа. Если для документа не установлено свойство цвета, то среда (используя параметры обозревателя или некие параметры среды) сама определяет используемый цвет. Этот процесс называется каскадированием стилей, потому что свойства последовательно передаются по иерархии контейнеров. Внутренний механизм для объектов DhStyle называется «каскадные таблицы стилей» (Cascading Style Sheets, CSS) от W3C.

Работа с динамическими таблицами

Работа с таблицами в действительности не отличается от работы с любой другой частью библиотеки; принципы и модель программирования применяются к таблицам так же, как и к другим типам элементов. Таблица, однако, является столь мощным и популярным элементом, что его стоит обсудить подробнее.

Для использования таблицы Вы создаете объект DhTable, добавляете в него объекты DhRow и затем добавляете в строки объекты DhCell. Вот правила применения таблиц:

Хотя это и кажется ограничением, но при помощи следующего кода легко создать простой контейнер, который эмулирует сетку таблицы: import com.ms.wfc.html.*;

public class GridBag extends DhTable {

int cols;

int currCol;

DhRow currRow;

public GridBag(int cols) {

this.cols = cols;

this.currCol = cols; }

public void add(DhElement e) {

if( ++this.currCol >= cols ) {

this.currRow = new DhRow();

super.add(currRow);

this.currCol = 0; }

DhCell с = new DhCell(); c.add(e);

this.currRow.add( с ); }

}

Чтобы использовать этот класс GridBag, просто задайте числа строк и столбцов (в данной реализации они должно быть одинаковыми), а затем присвойте элементы ячейкам. Вот пример кода в классе, производном от DhDocument, в котором используется

GridBag: protected void initForm() {

GridBag myTable = new GridBag(S);

for (int 1=0; i < 25; ++!){

myTable.add(new DhText("" + i));

setNewElements( new DhElement[] { myTable } );

} }

Комбинирование таблиц и объектов Style — одно из наиболее мощных применений библиотеки. Оно позволяет создавать нестандартные генераторы отчетов, которые профессионально выглядят и легко программируются.

Связывание данных с таблицами

Таблицы имеют возможность связывания данных. Используя объект com.ms.wfc.data.ui.DataSource, Вы свяжете данные с таблицей, как показано в следующем коде:

import com.ms.wfc.data. *;

import com.ms.wfc.data.ui.*;

void private initForm( ){

DhTable dataTable = new DhTable();

dataTable.setBorder( 1 );

dataTable.setAutoHeader( true );

DataSource dataSource = new DataSource();

dataSource.setConnectionString("DSN=Northwind");

dataSource.setCommandText("SELECT * FROM Products" );

// Если хотите использовать таблицу на сервере,

// вызовите dataSource.getRecordset(), чтобы заставить источник данных

// (DataSource) синхронно создавать набор записей (recordset);

// в противном случае вызовите dataSource.begin(), и таблица будет

// заполняться асинхронно по мере готовности набора записей.

if ( IgetServerMode() ){

dataSource.begin();

dataTable.setDataSource( dataSource );

} else

dataTable.setDataSource( dataSource.getRecordset() );

setNewElements( new DhElement[] { dataTable } );

}

Если Вам известен формат возвращаемых данных, можете также задать строку шаблона (повторителя), которую таблица будет использовать для форматирования возвращаемых данных. Для этого проделайте следующее.

  1. Создайте элемент DhTable: DhTable dataTable = new DhTable();
  2. Создайте строку шаблона и введите ее в таблицу; можно также создать строку заголовка. Для каждого элемента в ячейке шаблона, который будет принимать данные из набора записей, создайте объект DataBinding.

    DhRow repeaterRow = new DhRow();

    RepeaterRow.setBackColor( Color.LIGHTGRAY );

    RepeaterRow.setForeColor( Color.BLACK );

    DataBinding[] bindings = new DataBinding[3];

    DhCell cell = new DhCell();

    DataBinding[0] = new DataBinding( cell, "text", "ProductID" );

    repeaterRow.add( cell );

    cell = new DhCell();

    DataBinding[1] = new DataBinding( cell, "text", "ProductName" );

    cell = new DhCell();

    cell.setForeColor( Color.RED );

    cell.add( new DhText( "$" ) );

    DhText price = new DhText();

    price.setFont( Font.ANSI_FIXED );

    DataBinding[2] = new DataBinding( price, "text", "UnitPrice" );

    cell.add( price );

    repeaterRow.add( cell );

    // задать для таблицы строку повторителя и связывания

    table.setRepeaterRow( repeaterRow );

    table.setDataBindings( bindings );

    // Создать и задать строку заголовка

    DhRow headerRow = new DhRow();

    headerRow.add( new DhCell( "ProductID" ) );

    headerRow.add( new DhCell( "Product Name" ') );

    headerRow.add( new DhCell( "Unit Price" ) );

    table.setHeaderRow( headerRow );

  3. Создайте объект DataSource и настройте его на извлечение данных в требуемом формате.

    DataSource ds = new DataSource();

    ds.setConnectionString("DSN=Northwind");

ds.setCommandText("SELECT ProductID, ProductName,

UnitPrice FROM Products WHERE UnitPrice < 10" );

  1. Введите DataSource в объект DhTable.

table.setDataSource( ds );

ds. begin(); 5 Добавьте DhTable в документ.

setNewElements( new DhElement[] { table } ); // альтернатива:

add( table );

Теперь Ваша таблица заполнится данными из набора записей и отфор-чатируется в соответствии со строкой шаблона.

Использование пакета com.ms.wfc.html на сервере

Пакет com.ms.wfc.html используется также на сервере для поддержки программной модели генерации и передачи HTML на клиентскую страницу. В отличие от модели Dynamic HTML на стороне клиента, модель на стороне сервера является статической, поскольку класс Java-сервера не взаимодействует с клиентским документом. Вместо этого сервер компонует HTML-элементы и последовательно отсылает их клиенту в порядке появления в шаблоне HTML, если таковой задан. Это не вполне динамическая, но все же достаточно мощная функция сервера. Например, Вы вправе применить DhStyle-атрибуты ко всем частям некоего кода HTML-шаблона, а затем, просто изменяя их, гене-рировать страницы, совершенно непохожие друг на друга. Вам не нужно программно генерировать все изменения отдельных стилей. Другое преимущество в том, что Вы можете использовать одну и ту же модель для генерирования динамического HTML для клиентских и серверных приложений, тем самым облегчая изучение и запоминание генерирования HTML.

В настоящее время есть два режима генерации HTML на сервере. В обоих используется программирование Активных серверных страниц (Active Server Pages, ASP) и класс на основе классов из com.ms.wfc.html. Первый подход — ограниченный — предполагает больший упор на ASP-сценарий. Во втором используется класс, производный от DhDo-cument. Такой режим очень похож на модель, применяемую на клиенте, поскольку управление осуществляется преимущественно в классе, а не в сценарии.

Подход на основе ASP

При этом на серверной странице используются два метода ASP-сцена-рия: getObject и Response.Write. Метод getObject применяют для реализации класса, основанного на классах WFC из com.ms.wfc.html; метод Response.Write пишет клиенту сгенерированную строку HTML. Класс com.ms.wfc.html.DhElement поддерживает метод getHTML, который создает строку HTML; последняя посылается на клиентскую страницу с помощью ASP-метода Response.Write.

Предположим, Bam класс MyServer является расширением DhForm и включает в себя некоторые элементы HTML. В своем ASP-сценарии Вы сначала вызываете getObject(«java:MyServer») для создания объекта DHTML. Затем внутри сценария Вы можете выполнить любые действия над объектом, например установить его свойства. По окончании вызовите метод getHTML-объекта для генерации строки и передайте результат в метод Response.Write, который перешлет HTML клиенту. В следующих фрагментах показаны соответствующие места ASP-сценария и Java-кода по созданию объекта управления DhEdit в HTML и передаче его клиенту.

ASP-сценарий

Dim f,x

set f = getObject( "java:dhFactory" )

set x= f.createEdit

x.setText( "I'm an edit!" )

Response.Write( x.getHTML() )

Response.Write( f.createBreak().getHTML() )

JAVA-код

public class dhFactory {

public dhFactory(){ }

public DhBreak createBreak() {

return new DhBreak(); }

public- DhEdit createEdit(){

return new DhEdit(); } }

Подход на основе HTML

Этот подход чуть сложнее и ближе к клиентской модели. Он также использует ASP-сценарий для доступа к классу DhDocument, но все остальные действия программируются на Java. Как и в клиентской модели, класс DhModule создается как Java-компонент на Web-странице и автоматически вызывает метод initForm в классе, производным от DhDocument.

Как и в клиентской модели, все начальное связывание осуществляется в вызове initForm. Функция onDocumentLoad также вызывается для класса на стороне сервера. В этом методе Вы получите доступ к объектам IIS Response и Request (используя методы getResponse и getRequest класса DhModule), а также добавите новые элементы DhElement в поток документа. Однако важно1 понимать, что нельзя в документе на серверной стороне использовать функции уровня документа, например findElement, или операции перечисления, за исключением перечисления элементов, которые явно были добавлены в класс, производный от DhDocument.

Чтобы использовать подход на основе HTML, выполните следующие действия.

  1. Создайте серверный класс Java (на основе DhDocument).
  2. В этом классе реализуйте метод initForm так же, как это делалось бы в клиентском приложении.
  3. Из ASP-сценария вызовите метод Server.CreateObject, передав ему «DhModule» для создания объекта DhModule.
  4. Вызовите метод DhModule.setCodeClass, передав ему имя класса, производного от DhDocument.
  5. Вызовите метод DhModule.setHTMLDocument, передав ему в качестве шаблона (если таковой есть) полный локальный путь к файлу с Вашей серверной Web-страницей.

Если вызывать setHTMLDocument, передав ему пустую строку («»), то класс DhDocument выполнится и выведет HTML для любого элемента, добавленного в ASP к моменту вызова setHTMLDocument. Затем Вы можете сгенерировать секции встроенного HTML-кода. Если не вызвать setHTMLDocument, то класс DhDocument выведет весь HTML-код для страницы, включая тэги <HTML>, <HEAD> и <BODY>. В следующем примере показана ASP-страница, использующая шаблон:

<% Set mod = Server.CreateObject( "com.ms.wfc.html.DhModule" )

mod.setCodeClass( "Classl" )

mod.setHTMLDocument( "c:\inetpub\wwwroot\Page1.htm" ) %>

Во время выполнения среда поймет, что класс выполняется на сервере, и отреагирует соответственно.

После создания производного от DhDocument класса добавьте в него элементы или текст. Они будут добавлены к любому шаблону, заданному перед тэгом </BODY>.

Ниже демонстрируется класс, который работает как на сервере, так и на клиенте.

import com.ms.wfc.ui.*; import com.ms.wfc.html.*;

public class Class"! extends DhDocument { public Class1(){

initForm(); }

DhText txtl = new DhText(); DhForm sect = new DhForm();

private void initFormO {

// вызвать getServerMode() для проверки,

// выполняется ли объект на сервере

if ( getServerMode() ){

txt1.setText( "Hello from the server!" ); }else{

txt1.setText( "Hello from the client!" ); }

// задать размер секции, цвет ее фона

// и добавить в нее элемент txtl

sect.setSize( 100, 100 );

sect.setBackColor( Color.RED );

sect.add( txtl );

add( sect );

setNewElements( new DhElement[] { sect } ); } }

Если требуется связывание с HTML-документом, расположенным на странице, используйте метод DhDocument.setBoundElements точно так же, как это делалось бы и на клиенте. Например, пусть Ваш HTML-шаблон содержит следующий код: <Р>

The time isKSPAN id=txt1X/SPANXBR>

<INPUT type=text id=edit1 value=""> </P>

Ваш метод initForm выглядит примерно так:

DhText txtl = new DhText(); DhEdit edit = new DhEdit();

DhComboBox cb = new DhComboBox();

private void initFormO{

txtl.setText(com.ms.wfс.app.Time().formatShortTime());

edit.setText("Hello, world!"); edit.setBackColor( Color. RED );

setBoundElements( new DhElement[]{ txtl.setBindID( "txtl" )

edit.setBindID( "editV ) } );

// Создать комбинированный список, который должен быть добавлен после

// связанных элементов cb.addltem( "One" );

cb.addltem( "Two" );

// Добавить элементы в конец документа.

setNewElements( new DhElenent[]{ cb }); }

Различия между интерпретацией классов HTML на клиенте и сервере невелики — за одним важным исключением. После того как элементы записаны (отправлены клиенту), они не могут быть изменены так, как это делается на клиентском документе. Исключение DhCantModifyElement, существенное только для серверных приложений, генерируется на записанном элементе, если делается попытка изменить его снова. (Это подчеркивает тот факт, что между серверным Java-классом и клиентским документом нет той реальной взаимосвязи, какая действует на клиенте между Java-классом и документом: сервер полагает, что после записи элемент недоступен.)

Одно из преимуществ использования метода, производного от DhDocument, в том, что можно реализовать HTML-шаблон, который дополнен атрибутами, распознаваемыми классами com.ms.wfc.html. Дополнив элементы HTML в файле идентификаторами атрибутов и затем задав соответствующие идентификаторы в исходном коде, использующем метод DhElement.setBindlD, Вы осуществите связывание с этими HTML-элементами, сможете устанавливать их свойства, добавлять свой встроенный HTML-код и т. д. Это, по существу, позволяет заранее проектировать и кодировать отдельные шаблоны, а затем заполнять шаблон динамическими данными, когда документ будет запрошен с сервера.

к оглавлению   к 4GL - визуальному программированию

Знаете ли Вы, что такое мысленный эксперимент, gedanken experiment?
Это несуществующая практика, потусторонний опыт, воображение того, чего нет на самом деле. Мысленные эксперименты подобны снам наяву. Они рождают чудовищ. В отличие от физического эксперимента, который является опытной проверкой гипотез, "мысленный эксперимент" фокуснически подменяет экспериментальную проверку желаемыми, не проверенными на практике выводами, манипулируя логикообразными построениями, реально нарушающими саму логику путем использования недоказанных посылок в качестве доказанных, то есть путем подмены. Таким образом, основной задачей заявителей "мысленных экспериментов" является обман слушателя или читателя путем замены настоящего физического эксперимента его "куклой" - фиктивными рассуждениями под честное слово без самой физической проверки.
Заполнение физики воображаемыми, "мысленными экспериментами" привело к возникновению абсурдной сюрреалистической, спутанно-запутанной картины мира. Настоящий исследователь должен отличать такие "фантики" от настоящих ценностей.

Релятивисты и позитивисты утверждают, что "мысленный эксперимент" весьма полезный интрумент для проверки теорий (также возникающих в нашем уме) на непротиворечивость. В этом они обманывают людей, так как любая проверка может осуществляться только независимым от объекта проверки источником. Сам заявитель гипотезы не может быть проверкой своего же заявления, так как причина самого этого заявления есть отсутствие видимых для заявителя противоречий в заявлении.

Это мы видим на примере СТО и ОТО, превратившихся в своеобразный вид религии, управляющей наукой и общественным мнением. Никакое количество фактов, противоречащих им, не может преодолеть формулу Эйнштейна: "Если факт не соответствует теории - измените факт" (В другом варианте " - Факт не соответствует теории? - Тем хуже для факта").

Максимально, на что может претендовать "мысленный эксперимент" - это только на внутреннюю непротиворечивость гипотезы в рамках собственной, часто отнюдь не истинной логики заявителя. Соответсвие практике это не проверяет. Настоящая проверка может состояться только в действительном физическом эксперименте.

Эксперимент на то и эксперимент, что он есть не изощрение мысли, а проверка мысли. Непротиворечивая внутри себя мысль не может сама себя проверить. Это доказано Куртом Гёделем.

Понятие "мысленный эксперимент" придумано специально спекулянтами - релятивистами для шулерской подмены реальной проверки мысли на практике (эксперимента) своим "честным словом". Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМАФорум Рыцари теории эфира
Рыцари теории эфира
 20.10.2019 - 19:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> КОМПЬЮТЕРНО-СЕТЕВАЯ БЕЗОПАСНОСТЬ ДЛЯ ВСЕХ - Карим_Хайдаров.
20.10.2019 - 19:29: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ЗА НАМИ БЛЮДЯТ - Карим_Хайдаров.
19.10.2019 - 18:18: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Марины Мелиховой - Карим_Хайдаров.
18.10.2019 - 14:00: ЭКОЛОГИЯ - Ecology -> Биохимия мозга от проф. С.В. Савельева и не только - Карим_Хайдаров.
18.10.2019 - 07:39: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
18.10.2019 - 07:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вячеслава Осиевского - Карим_Хайдаров.
18.10.2019 - 07:26: ЭКОНОМИКА И ФИНАНСЫ - Economy and Finances -> КОЛЛАПС МИРОВОЙ ФИНАНСОВОЙ СИСТЕМЫ - Карим_Хайдаров.
17.10.2019 - 18:29: ЭКСПЕРИМЕНТАЛЬНАЯ ФИЗИКА - Experimental Physics -> Ядерные эксперименты - Карим_Хайдаров.
17.10.2019 - 06:01: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
16.10.2019 - 19:24: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Ю.Ю. Болдырева - Карим_Хайдаров.
13.10.2019 - 18:09: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Светланы Вислобоковой - Карим_Хайдаров.
13.10.2019 - 08:05: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Декларация Академической Свободы - Карим_Хайдаров.
Bourabai Research Institution home page

Bourabai Research - Технологии XXI века Bourabai Research Institution