faqs.org.ru

 Главная > Программирование > Web-программирование >

FAQ по языку Java

Секция 5 из 7 - Предыдущая - Следующая
Все секции - 1 - 2 - 3 - 4 - 5 - 6 - 7

URL соединениям быть инициироваными извне firewall'а. Подумайте об этом!
Если бы это было так, то firewall не выполнял бы свою работу.

Также отметтье, что существуют соответствующие socksProxyPort и
socksProxyHost когда socks используются вместо прокси. Socks порт по
умолчанию - 1080.

*(Секция 15) Что означает "swizzle"(неточный синоним - взбить[коктейль]),
например "Swizzle an object?"

[*] Это означает сериализовать. "To swizzle an object" означает рекурсивно
сериализовать созданные объекты.

*(Секция 15) Я использую возможности ссериализации в 1.1 чтобы сохранить
некоторые объекты на диске. Я добавил новое поле в один из моих объектов,
который сериализуется и теперь десериализация моих старых объектов больше
не работает. Я получаю такое исключение :


java.io.InvalidClassException: MacroData; Local class not compatible


[*] Вам нужно добавить объявление типа


    static final long serialVersionUID = 4021215565287364875L;


в модифицированный класс. Актуальное значение этого длинного целого
предоставляется утилитой "serialver", которая есть в JDK. Любая отличная от
первой версия класса требует, чтобы эта статическая переменная была
определена в классе.

*(Секция 15) Мой код работающий с сокетами выглядит правильным, но не
работает!

[*] При использовании сокетов Вы обычно открываете оба входящий и исходящий
потоки. TCP соединение является полнодуплексным, но либо отсылающая, либо
принимающая стороны могут закрываться независимо. По умолчанию, когда
установлено что удаленная сторона закрыла соединение, локальная сторона
просто закрывает его. Проверьте, может быть это случается с Вами
добавлением соответствующей пары. Используйте tcpdump чтобы проверить это.

*(Секция 15) Как мне получить соответствие IP адреса и имени хоста?

[*] В Java 1.1 (ранние версии были глюкавыми) используйте:


    String host = InetAddress.getByName("211.10.2.119").getHostName();


*(Секция 15) Как мне встроить якорь (anchor) в URL? Просто поместить его
как часть строки в конструктор не работает.

[*] Что-то типа:


    URL url = new URL("http://www.my_domain.com/my_page.html");
    URL anchor = new URL(url, "#section2");
    this.getAppletContext().showDocument(anchor);

*(Часть 10) Я использую add(Component), чтобы добавить компоненты в
контейнер. Есть ли способ явного указания z-порядка этих компонент?

[*] В JDK 1.0 нет явного способа установить z-порядок компонент. Вы можете
попробовать экспериментально подобрать его с помощью используемого вами
броузера, или Вы можете использовать CardLayoutManager, чтобы
удостоверится, что необходимая вам панель спереди.

В JDK 1.1 z-порядок компонент ("z-порядок" означает порядок
"спереди-сзади", т.е. какое окно перед каким находится) управляется
посредством метода add(Component comp, int index). По умолчанию компоненты
добавляются от 0 до N. Метод класса Container paint отрисовывает его
видимые компоненты от N до 0.

*(Часть 10) Как я могу получить размеры и разрешение экрана?

[*] Используйте

java.awt.Toolkit.getDefaultToolkit().getScreenSize()

или

java.awt.Toolkit.getDefaultToolkit().getScreenResolution()

Разрешение экрана возвращается в точках-на-дюйм (dpi, dots-per-inch).

Загляните в класс Toolkit - там много полезных методов

Toolkit.getDefaultToolkit().getColorModel().getPixelSize()

возвращает цветовую модель в битах-на-пиксел (bpp, bits-per-pixel)

Math.pow(2, Toolkit.getDefaultToolkit().
    getColorModel().getPixelSize())

возвращает цветовую модель в виде количества цветов. Или используйте это:

1 << Toolkit.getDefaultToolkit().
    getColorModel().getPixelSize()

Степень 2 вычисляется как двоичный сдвиг 1.

*(Часть 10) Как я могу учесть размеры заголовка и рамки при отрисовке
Frame'а?

[*] Используйте метод MyFrame.getInsets(). Он возвращает объект
java.awt.Insets который имеет четыре целых поля: top, left, bottom, right,
которые дают количество пикселов для каждого из полей, откладываемых
сверху. Вы можете использовать эти значения, чтобы отрегулировать объект
Dimension, возвращаемый Сomponent.getSize().

Если Вы это делаете это в конструкторе, Вам необходимо удостоверится, что
Peer объект Frame'а уже создан. Иначе объект Insets, возвращаемый
getInsets(), будет состоять из нулей. Вызовите Frame.addNotify(), чтобы
спровоцировать создание Peer'а.

*(Часть 10) Как нужно изменять pазмеpы списка? Я объявил список как

List tlist = new List(10);

но стpоки в списке были длиной 80 символов и только 15 первых были
показаны. Мне не удалось изменить размер списка, чтобы показать его
содержимое, не прибегая к использованию полос прокрутки.

[*] Нельзя изменять размер списка в конструкторе, так что добавте следующие
строки в Applet (или где бы то ни было):

public void paint (Graphics g) {
    tlist.setSize(200,200);
}

Потом перед тем как показать Panel/Frame со списком:

tlist.resize(400,400);

*(Часть 10) Как мне узнать, когда произошло изменение размеров окна?

[*] Перегрузите метод Component.setBounds(int, int, int, int), что бы
делать то что Вам необходимо. Конечно, Вам так же нужно вызывать
super.setBounds(). Необходимо заметить, что setBounds() заменил устаревший
(deprecated) метод reshape().

Заметьте, что новое API вызывает не что иное как устаревшее API. Например
Component.setBounds вызывает Component.reshape, но не reshape вызывает
setBounds. Это происходит потому, что AWT часто требуется вызывать его для
своих собственных нужд. Если AWT вызовет старый метод, затем новый метод, и
Вы перегрузили новый метод, AWT (что есть неправильно) не вызовет Вашу
процедуру. В случае если AWT вызывает новый метод (а он в свою очередь
вызывает старый), любые перегрузки нового метода будут корректно вызваны
AWT по необходимости. Если вышесказаное вам не понятно, просто забудте это.

*(Часть 10) Как мне отцентрировать диалоговое окно?

[*] На текущий момент, Вы не можете получить абсолютные координаты апплета
на экране. Его положение (0,0) относительно броузера, а не экрана. Но вы
можете отцентрировать нечто, что всплывает или показывается, на экране с
помощью кода, как этот:

Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
my_window.move(
 ( screen.width - my_window.size().width ) / 2,
 ( screen.height - my_window.size().height ) / 2 );

my_window.show().

В подобной манере, Вы можете отцентрировать нечто относительно его предка.
Обратите внимание на умное использование такого API, как translate(),
которое делает работу за Вас:

void center(Component parent) {
    pack();

    Point p = parent.getLocation();
    Dimension d = parent.getSize();
    Dimension s = getSize();

    p.translate((d.width - s.width) / 2,
                (d.height - s.height) / 2);
    setLocation(p);
}

*(Часть 10) Как я могу получить абсолютные координаты мыши?

[*] Вы имеете в виду, что если размеры броузера 640x480, Вы хотите получить
Y-координату в диапазоне от 0 до 480. А если окно броузера около 800х600,
то в диапазоне от 0 до 600. Это может понадобится для всплывающий меню,
когда вы хотите его показать по абсолютным координатам мыши.

Метод заключается в анализе событий мыши и положений указателя и его
родителей пока не будет родителя. Хотя для некоторых броузеров это
неприменимо. [Ждем лучших предложений.]

*(Часть 10) Как я могу определить изменение размера фpейма или другого
компонента?

[*] Если Вы используете JDK 1.0.2, Вы можете перегрузить метод
Component.reshape(int, int, int, int) что бы делать все что Вам необходимо,
конечно необходимо вызывать super.reshape().
В JDK 1.1.х, setBounds() пришел на смену reshape(), тем не менее существует
путь лучше, чем перегрузка метода setBounds(), для определения изменения
размеров - использовать новую модель событий. Заметьте, что новое API
вызывает устаревшее.

Приемлимый путь определения изменения размеров в JDK 1.1.х это
зарегистрировать ComponentListener на Frame'е, приблизительно так:

import java.awt.*;
import java.awt.event.*;

class MyFrame extends Frame {
    public MyFrame() {
        addComponentListener(new CmpAdapter());
    }

    class CmpAdapter extends ComponentAdapter {
        public void componentResized(ComponentEvent evt) {
            //doSomething();
        }
    }
}

Иначе такого же эффекта можно добится таким образом:

class MyFrame extends Frame implements ComponentListener {
    public MyFrame() {
        addComponentListener(this);
    }

    public componentHidden(ComponentEvent evt) { }
    public componentMoved(ComponentEvent evt) { }
    public componentShown(ComponentEvent evt) { }
    public componentResized(ComponentEvent evt) {
        //doSomething
    }
}

Или так:

  public MyFrame() {
          addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent evt) {
              // doSomething;
        }
      } );
    }

*(Часть 10) Для чего предназначены методы Component preferredSize() и
minimumSize()?

[*] Эти методы позволяют LayoutManagerу вычислять продпочтительный и
минимальный размеры компонент, которые он упорядочивает. Вы можете
управлять значениями, котрые использует LayoutManager, создавая подклассы
используемых вами компонентов и перегружая эти методы. Вы их не вызываете,
Вы перегружаете их и они вызываются из вне.

*(Часть 10) Но разве AWT не может просто запомнить, что было выведено в
данный контекст Graphics и продублировать это вместо того, чтобы вызывать
paint()?

[*] Наверное, может, но как вы сможете отменить что-то, что уже было
нарисовано? Как вы сможете начать рисование заново, с другим содержимым?
Эти проблемы можно решить, если ввести дополнительные методы, но это не
лучший выход. На практике гораздо проще иметь возможность взглянуть на
метод paint и увидеть все, что будет сделано при перерисовке этой
компоненты. Итог: Используйте paint(), а не g=getGraphics(); g.drawString(
...

*(Часть 10) Когда я часто вызываю repaint(), половина моих запросов
теряется и не отображается на экране. Почему?

[*] repaint() только сообщает AWT, что вы хотите, чтобы произошла
перерисовка. AWT соберет несколько последовательных запросов на перерисовку
в один, так что будет выполнена только самая последняя перерисовка. Один из
возможных обходных путей - использовать отсекающий прямоугольник и
перерисовывать только те участки, которые были изменены.
*(Часть 10) Почему я получаю это сообщение, если использую JDK 1.1 под X
Windows?

java.lang.NullPointerException
at sun.awt.motif.MFramePeer.<init>(MFramePeer.java:59)
at sun.awt.motif.MToolkit.createFrame(MToolkit.java:153)
at java.awt.Frame.addNotify(Frame.java)
at java.awt.Window.pack(Window.java)

[*] В вашей системе отсутствует шрифт. Переименуйте font.properties из
подкаталога "lib" в font.properties.bak. Тогда JDK не будет искать
несуществующий шрифт.

Эта проблема возникает, поскольку библиотеки Motif AWT используют шрифт
"plain Dialog 12 point" в качестве шрифта по умолчанию. К несчастью, если
используется удаленный X сервер, это шрифт иногда недоступен.

Для X терминала диагностические сообщения могут слегка отличаться:

% appletviewer HelloWorldApplet.html
SIGSEGV 11* segmentation violation
si_signo [11]: SIGSEGV 11* segmentation violation
si_errno [0]: Error 0
si_code [1]: SEGV_ACCERR [addr: 0x14]

Для того, чтобы определить, какие шрифты имеются у вас в наличии,
используйте команду вида

xlsfonts > ~/fonts.txt

Затем пройдитесь по длинному списку шрифтов и выберите те, которые хотите
использовать. Программа xfd демонстрирует выбранный шрифт:

xfd -fn "имя вашего шрифта" &

*(Sect. 10) Почему GridBagLayout так сложно использовать?

[*] Для этого есть две причины. Во-первых, хотя небольшие упаковки довольно
просты, детализированная упаковка для GUI очень сложна. Во-вторых, при
разработке GridBagLayout человеческий фактор и простота использования не
были основной целью. Если это вас раздражает (меня это раздражает), не
используйте GridBagLayout. Разместите свой GUI на нескольких панелях и
используйте для каждой из них свой менеджер упаковки, чтобы достичь нужного
вам эффекта. Официальное объяснение, данное руководителем проекта AWT
участникам Mountain View Java Users Group 4 декабря 1996, звучит так:

     "Так случилось, и это уже принято к сведению, что GridBagLayout
     слишком сложен для того, чтобы выполнять возложенные на него функции.
     GBL будет по-прежнему поддерживаться, но также будет вскоре выпущен
     улучшенный и упрощенный вариант. Этот 'улучшенный GBL' может быть
     использован вместо GBL."

Итог: не нужно тратить усилий на GBL, на данный момент существуют более
простые альтернативы. К тому же, GBL является причиной утечки памяти. GBL
вставляет "добавленные" компоненты в хэш-таблицу, но
removeLayoutComponent() их никогда не удаляет. См. ошибку номер 4195295.

Трудно пройти мимо документации по GBL. Основываясь на очевидном сходстве,
ее можно взять из grid layout manager из Tk (Tcl/Tk). Если вам не нравятся
вложенные панели и ни один из других менеджеров упаковки не делает того,
что вам нужно (или вы работаете с унаследованным кодом, который уже его
использует), документация из Tk может вам пригодиться.

*(Часть 10) MyClass работает отлично, за исключением случая, когда я хочу
установить другой шрифт. Я не могу заставить это работать под Win95, но то
же самое работает под MacOS и Unix.

[*] Вы, скорее всего, указали шрифт, который отсутствует в вашей поставке
Win95; это одно из различий между платформами, на которые вы можете
натолкнуться, если используете специфику одной из платформ, например,
задаете "Arial" в качестве шрифта и рассчитываете, что это будет работать
на платформах, отличных от Windows.

Для Windows 95 и Solaris 2.6 эти шрифты

   * Dialog
   * SansSerif
   * Serif
   * Monospaced
   * Helvetica
   * TimesRoman
   * Courier
   * DialogInput
   * ZapfDingbats

обнаружены следующей программой:

import java.awt.*;

class foonly {
    static public void main(String s[])
    {
        String n[]= new Frame().getToolkit().getFontList();
        for (int i=0;i<n.length; i++)
            System.out.println(n[i]);

        System.exit(0);
    }
}

Другими словами, вы можете получить массив типа String имен шрифтов,
используя

String[] fonts = Toolkit.getDefaultToolkit().getFontList()

Вместо настоящих имен шрифтов, таких как Helvetica, TimesRoman, и Courier в
JDK 1.1 было отдано предпочтение стилям, таким, как SansSerif, Serif, и
Monospaced (соответственно). Стиль шрифта будет отображаться в наиболее
подходящий шрифт для данной платформы.

В настоящий момент для отображения стилей в имена системных шрифтов
используются записи в одном из файлов font.properties в $JAVAHOME/lib.
Имеется несколько файлов font.properties, соответствующих разным
локализациям. Если вам нужно быстро протестировать новый шрифт, вы можете
изменить файл или дополнить его так, что отображение будет производиться в
тот шрифт, который вы хотите проверить.

*(Часть 10) Я создал Lightweight-компоненту (компоненту, непосредственно
расширяющую класс Component), но она мерцает/не перерисовывается как
следует. Почему?

[*] Lightweight-компоненты, поскольку они считаются "прозрачными", не
перерисовываются непосредственно в ответ на repaint(). Фактически
Component.repaint() просматривает стек компонент снизу вверх, находит
"непрозрачную" Heavyweight-компоненту (она должна быть контейнером), и
затем вызывает *ее* метод repaint().

Из этой точки управление в итоге передается методу Container.update().
Первое, что он делает - вызывает super.update, приводя нас к
Component.update(), который очищает компоненту цветом фона, поскольку он
был вызван для heavyweight-компоненты, и завершается. Затем
Container.update() вызывает update рекурсивно для всех
Lightweight-компонент, которые этот контейнер содержит.

Итог: "прозрачность" lightweight-компонент будет работать правильно (без
мерцания) если первая доступная выше по иерархии включения
heavyweight-компонента является

   * heavyweight-компонентой с двойной буферизацией (она должна быть
     контейнером), или
   * heavyweight-компонентой, которая никогда не обновляется, а только
     перерисовывается (т.е. такой, где метод update() перекрыт и фон по
     умолчанию не очищается).

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

Другой важный момент состоит в том, что если ваш контейнер определяет
собственный метод paint(), то он обязан вызывать super.update/paint(),
иначе содержащиеся в нем lightweight-компоненты никогда не будут
перерисованы. Собрав это воедино, мы видим, что в данном случае для
нормальной работы нужно внесение минимальных изменений в код - поместить
метод

public void update(Graphics g) {
    super.paint(g);
}

в ближайший в иерархии компонент heavyweight-контейнер, содержащий
lightweight-компоненты, которые ничего не выводят в тех областях, которые
уже были прорисованы их родителями, т.е. "непрозрачные" компоненты. Грязно,
но быстро.

Если вы хотите нормально работать с прозрачными компонентами, описанный
выше метод заменяется на

  public void update(Graphics g) {
    // стандартное создание внеэкранного контекста.
    offg.fillRect(нужный цвет фона, полный размер);
    super.paint(offg);
    g.drawImage(myimage, 0, 0, null);
    }

  public void paint(Graphics g) {
    // на случай изменения размера может вначале вызывать update().
    super.paint(offg);
    g.drawImage(myimage, 0, 0, null);
    }

Их можно объединить, если заставить this.update() вызывать this.paint(), с
подстановкой различных значений параметров, но проще всего перекрыть их по
отдельности, как в примере.

*(Часть 10) В чем разница между методом setForeground(Color c) класса
Component и setColor(Color c) класса Graphics?

[*] Во первых, эти два метода делают одно и тоже: устанавливают цвет в
значение параметра. Разница в том, где это испоьзуется. Есть еще
Component.setBackground, который устанавливает цвет фона.

Если Вы пишите конструктор или обработчик события (вроде "Нажмите здесь
чтобы сделать рисунок синим"), то у вас есть Component и нужно использовать
метод setForeground(). А вот в меттоде paint() у вас есть аргумент типа
Graphics, и поэтому обычно используется g.setColor(c).

В отличие от класса Component, класс Graphics не имеет независимых цвета
фона и цвета рисунка. Графический обьект поступает с цветом, полученым от
рисуемой поверхности. Но после вызова setColor() вся графика будет
рисоваться указаным цветом. Так как эти методы делают разные вещи, названы
они по разному.

*(Часть 10) Когда я двигаю мышью с нажатой кнопкой в Component и затем
сдвигаю мышь с Component, то все события посылаются в тот Component, хотя
курсор и вне его. Это ошибка?

[*] Нет, это особое свойство. Документация о Java API гласит:

     "... При нажатой кнопке мыши события о движении мыши посылаются в
     компонент даже когда курсор выходит за пределы компонента. Это
     продолжается до тех пор, пока кнопка не будет отпущена..."

Это сделано для удобства и облегчения программирования. Вы можете
обрабатывать "претаскивания" с место на место. Если это вам не нужно, то
просто проверте координаты события, и игнорируйте их, если они происходят
вне компонента.

*(Часть 10) Почему мои окна не закрываются, когда я нажимаю на кнопку
закрытия в заголовке?

[*] Вот как нужно делать:

   * JDK 1.0.2: перехватывайте Event.WINDOW_DESTROY и вызывайте методы
     hide() и dispose() для Frame.
   * JDK 1.1:
        o Слушайте события WindowEvent и в методе windowClosing() вызывайте
          hide() и dispose(). Это должно было быть действие по умолчанию, и
          наконец это сделано в Swing'овском JFrame.
        o Разрешите события типа AWTEvent.WINDOW_CLOSING и вызывайте hide()
          и dispose() в етоде processWindowEvent().
   * JDK 1.2: Компонент JFrame по умолчанию сам закрывется при нажатии на
     копку закрытия (см. раздел 10).

*(Часть 10) Как принудительно синхронизировать графические операции,
например, смену курсора или анимацию?

[*] Это делается методом sync() в Toolkit. Вот так:

AnyComponent.getToolkit().sync();

*(Часть 10) Как с помошью клавиши Tab передвигать фокус по компонентам?

[*] В JDK 1.0 Вы должны сами реагировать на нажатие клавиш и самому
программировать передвижению. JDK 1.1 поддерживает Tab и Shift+Tab (назад)
автоматически. Фокус передвигается в том порядке, в каком компоненты были
помещены в контейнер.

*(Часть 10) В чем разница между "низкоуровневыми" и "семантическими"
событиями?

[*] Низкоуровневые события связаны с конкретным компонентом (изменение
размера окна, движение мышью, нажатие клавиши, добавление компонента в
контейнер и т.п.). Семантические события возникают, когда Вы действуете на
управляющий компонент (двигаете линейку прокрутки, нажимаете на кнопку,
выбираете пункт меню и т.п.), и такой тип событий может быть генерирован
несколькими разными компонентами. Button и List генерируют событие Action
когда Вы на них нажимиете.

Самым главным для программиста является то, что Вы можете изменять
низкоуровневые события, как, например, значение клавиши в событии о нажатии
клавиши, при этом новое значение будет отображено. Кроме того, Вы сами
можете "потребить" такое событие, и оно не будет доставлено компоненту. Но
с семантическими событиями такое не пройдет - они уже попало в компонент.

Семантические события: используйте addXListener() чтобы добавить слушателя,
который реализует интерфейс XListener и может получать события типа XEvent.
Низкоуровневые сообытия: используйте метод enableEvents() и перекройте
performX(), чтобы перехватывать события в самом объекте.

*(Часть 10) Возможно ли сделать так, чтобы окно в Java плавало поверх
других? Например, колонка инстраментов плавает над обычными окнами, в
которых эти инструменты используются...

[*] В MS Windows обьект типа Window плавает поверх других окон, в отличие
от Frame, который находится внизу как обычное окно. такое поведение дает
"плавающий" эффект. Но обязательно ли должно Window плавть поверх других -
это совершенно другой вопрос.

На Макинтошах Window либо лежит так же как и обычные окна, либо полностью
модальное - в зависимости от VM, которую Вы используете. В Java нет легкого
способа добиться такого поведения. Если кто-нибудь знает такой способ,
пожалуйста, поделитесь.

*(Часть 10) Могу ли я свернуть/развернуть окно в Java?

[*] В JDK 1.1 не было способа сделать это. В JDK 1.2 эта возможность
появилась:

     MyFrame.setState( Frame.ICONIFIED );
     MyFrame.setState( Frame.NORMAL );

делает это. Установите нужное состояние.

*(Часть 10) Как узнать, какая кнопка мыши была нажата и сколько раз?

[*] Для обработки событий мыши Вы должны осуществить интерфейс
MouseListener либо расширить класс MouseAdapter и чтобы переопределить один
из методов обработки событий мыши. Аргумент типа MouseEvent, передаваемый в
методы, содержит поля, говорящие о том, какая кнопка нажата, и счетчик
нажатий. Используйте что-то вроде:

public void mouseClicked(MouseEvent m) {
 boolean leftButtonPush   =
    (m.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK) != 0;
 boolean centerButtonPush =
    (m.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0;
 boolean rightButtonPush  =
    (m.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0;

 int click = m.getClickCount();    // может быть 1, 2, 3 щелчка или больше

Вы можете вызвать m.isPopupTrigger(). Если этот метод возвращает true, то
пользователь запросил всплывающее меню. Во многих системах правая кнопка
служит для вызова таких меню.

Вы можете перекрыть метод processMouseEvent для Вашего компонента.

public void processMouseEvent(MouseEvent e) {
    if (e.isPopupTrigger())  {
       // делайте что хотите
    }
    else
      super.processMouseEvent(e);
  }

Этот код подходит для JDK 1.1. Кроме того, в JDK 1.2 можно вызвать
java.awt.swing.SwingUtilities.isRightMouseButton(MouseEvent me).

См. вопрос 15.10.

                       ------------------------------

11. Swing

  1. (Часть 11) Что такое Swing?

     [*] Swing - это новая оконная библиотека, включеная в JDK 1.2, и
     доступная как дополнительная библиотека для JDK 1.1. Swing входит в
     Java Foundation Classes и поддерживает оконую библиотеку, которая дает
     разроботчикам создавать компоненты, которые могут иметь изменяемый
     внешний вид и поведение. С точки зрения архитектуры, Swing расширяет
     (но не заменяет полностью) Abstract Windowing Toolkit (AWT).

     Swing содержит множество компонент, которые можно использовать вместо
     компонентов AWT (JFrame вместо Frame, JButton вместо Button, JApplet
     вместо Applet, JPanel вместо Panel и т.п.) Кроме того, есть есть
     компоненты, не имеющие аналогов в AWT (панели и линейки инструментов,
     линейки прогресса и др.) Тем не мене, в основе Swing лежит AWT.

     Swing позволяет создавать компоненты столь же сложные, как и в
     платформо-зависимых оконных библиотеках, как, например, MFC - и в
     соответсви с преимущесвами Java, все это будет работать на любых
     платформах. Изменяемый внешний вид означает, что компоненты могут
     иметь одинаковый вид на любой платформе, или же Вы можете сделать так,
     что окна будут выглядеть в стиле Windows на PC, в стиле Motif - на
     Unix-станции, либо по выбору пользователя.

     Кроме того, Swing подерживает Accessiblity API. Этот API позволяет
     адаптирующим программам для людей с физическими недостатками напремую
     взаимодействовать с Java VM и получать информацию о выполняемой
     программе; это применяется для работы с компонентами. Программы могут
     затем перевести это в форму, доступную пользователю (например,
     прочитать вслух текст в окне). Swing не использует платформо-зависимые
     компоненты, а адаптивные программы расчитаны на опрделенную платформу,
     Accessiblity API служит мостом между Swing и программой адаптации.
     Достоинством Accessiblity API является то, что для его поддержки
     разработчикам нужно сделать совсем немного, они должны сознавать это,
     если собираются добовлять новые компоненты.

     В Swing платформо-зависимыми являются лишь края окна, а также такие
     вещи, как шрифты и буфферы. Все остальное - композиция, расположение и
     отрисовка - контролируется программным кодом на Java. Таким образом,
     одинаковый код создает и управляет интерфейсом пользователя на любой
     платформе. Swing обеспечивает одинаковое поведение програмыы на разных
     платформах.

     Swing работает с JDK 1.1, скачайте файл swing.jar и добывте его в путь
     поиска классов. Swing встроен в JDK 1.2, и Javasoft недавно сменила
     название пакета на javax.swing.

*(Часть 11) Почему курсор, определенный как курсор ожидания (WAIT_CURSOR),
изменяется только, когда находится над некоторыми компонентами?
или
Как изменить обычный курсор на курсор ожидания над любой из областей окна,
включая его компоненты, для предотвращения каких-либо действий со стороны
пользователя во время обработки некоторого события? (Например доступ к базе
данных, открытие другого окна, загрузка изображения, сортировка данных и
т.д.)

[*] В JDK 1.0.2 изменять курсор мог только Фрейм awt. Начиная с JDK 1.1
работа с Курсором была перенесена в класс Component. Теперь все Компоненты
имеют доступ к классу Cursor.

Вы могли изменять Курсор на курсор ожидания для каждого из Компонентов. В
ряде случаев это отнимало немало времени, так как потенциально их у Вас
могло быть довольно много. Начиная с JFC Swing появился механизм для
изменения Курсора над всем Окном целиком, не считаясь с количеством
компонентов. Компонент библиотеки Swing - JFrame содержит метод:

             public void setGlassPane(Component glassPane)

который устанавливает Компонент awt как 'glassPane' для JFrame.

Этот Компонент перекроет всю, принадлежащую JFrame, доступную (видимую в
данный момент) область пользователя, исключая границу, установленную
отображающей оконной системой. Используя Компонент 'glassPane', Вы можете
включить 'Курсор ожидания' над всем JFrame, запрещая пользовательский ввод
(его полностью получает 'glassPane') и блокируя пользователя пока не
завершится 'другой' процесс.

ЗАМЕЧАНИЕ: Если Вы хотите видеть Курсор ожидания во время работы 'другого'
процесса, то необходимо создать Поток для выполнения последнего. Когда
происходит выполнение 'другой' работы, 'glassPane' отображает Курсор
ожидания и "проглатывает" весь ввод пользователя. По завершении 'другой'
работы, Поток использует Ваш метод waitCursor() чтобы скрыть 'glassPane' до
тех пор пока он не понадобится снова.

*(Часть 11) Почему компилятор сообщает, что метод "isCanselled()",
принадлежащий javax.swing.ProgressMonitor, не найден?

[*] В американском английском есть два допустимых варианта произношения:
"canceled" и "cancelled". Заметьте, что первый содержит одну "l", а второй
- две "ll". Sun использует вариант "canceled" для ProgressMonitor, но во
многих второстепенных исходниках из документации написано "cancelled". Еще
неприятней то, что в некоторых случаях Sun употребляет также и вариант
"cancelled", как например в названии метода "isCancelled()" для PrinterJob.

*(Часть 11) Почему нажатие на клавишу Enter не активизирует кнопку по
умолчанию в диалоговом окне библиотеки Swing?

[*] Раскладка клавиш по умолчанию для текстовых компонентов библиотеки
Swing (произошедших от JTextComponent) привязывает Enter (VK_ENTER) к
ActionEvent для текстовых полей. Это было сделано в целях сохранения
совместимости с работой java.awt.Textfield. Чтобы использовать клавишу
Enter для активизации кнопки по умолчанию, удалите привязку первой из
предлагаемой раскладки клавиш текстового компонента, как показано ниже:

    static {
      KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
      Keymap map =
           JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
      map.removeKeyStrokeBinding(enter);
    }

*(Часть 11) Как создавать непрямоугольные Компоненты?

[*] Взгляните на следующий пример, поставляемый вместе с JDK:
$JAVAHOME\demo\awt-1.1\lightweight\RoundButtons\example.html

                       ------------------------------

12. Браузеры

  1. (Часть 12) Когда же мой любимый браузер будет поддерживать Java 1.1?

     [*] В настоящий момент все популярные браузеры имеют поддержку JDK
     1.1. Netscape Communicator 4.04 с патчем "J" полностью поддерживает
     возможности Java 1.1. Он был выпущен в декабре 1997 года, и
     единственное, что там отсутствует,- поддержка JavaSoft для подписи
     апплетов (в этом вопросе Netscape пошла своим путем). Смотрите
     http://developer.netscape.com/support/faqs/champions/java.html#21
     Если Вы используете Netscape 4.05, и консоль сообщает что-нибудь
     отличное от Java 1.1.5, то значит Ваш Netscape не полностью
     поддерживает 1.1. Здесь находится специальная ознакомительная версия:
     http://developer.netscape.com/software/jdk/download.html

     В 1997 году Netscape ослабила поддержку Java в связи с захватом рынка
     компанией Microsoft. Microsoft использует IE, как стратегическое
     средство для внедрения того, что служащие этой компании называют
     "загрязненная Java" ("polluted Java"). Для обоих браузеров хорошим
     решением является Java Plug-in.

     Браузер фирмы Sun,- HotJava,- полностью поддерживает все возможности
     JDK 1.1. Людям, вынужденным пользоваться браузером без полной
     поддержки Java, следует применять Java Plug-In, заменяющий стандартную
     виртуальную машину Java, которой комплектуется браузер, и позволяющий
     использовать RMI, компоненты JavaBeans и Основные Классы Java (Java
     Foundation Classes) в Internet Explorer 3.02, 4.0 и 4.01. Java Plug-In
     также без проблем работает с браузерами Netscape. Его можно получить
     по адресу http://java.sun.com/products/.
     Заметьте, что надо немного изменить HTML для полной уверенности в том,

Секция 5 из 7 - Предыдущая - Следующая

Вернуться в раздел "Web-программирование" - Обсудить эту статью на Форуме
Главная - Поиск по сайту - О проекте - Форум - Обратная связь

© faqs.org.ru