Доступ к серверной базе данных из клиента в Java

Цель занятия

Изучение механизма доступа к базе данных, расположенной на сервере, из клиента. Реализация передачи и распаковки SQL- запросов. Получение результата выполнения SQL-запроса и передача результата на сторону клиента. Организация работы в сети. По данной проблеме можно также рекомендовать [1, 10, 11, 17].

Краткие теоретические сведения

Настоящее практическое занятие объединяет знания, полученные на практических занятиях, посвященных работе с базами данных, потоками и технологии "клиент-сервер". Хорошее усвоение материала этих занятий позволит вам без особого труда разобраться с материалом этого занятия.

Рассмотрим механизмы доступа к расположенной на сервере базе данных из клиента. Технология "клиент-сервер" применяется для централизованного доступа из удаленных ЭВМ к общей базе данных, расположенной на сервере. В языке Java механизм клиент-серверного взаимодействия основан на использовании потоков и сокетных соединений. Для клиента надлежит создать два потока: один поток для работы на ввод, второй — для работы на вывод. Аналогичная ситуация с сервером. В качестве языка запросов используем язык SQL.

Клиент должен обращаться в базу с сформированным SQL- запросом. Сервер должен выполнять запрос и возвращать ответ. Окно программы сервера предствлено на рис. 2.15.

Запуск сервера на выполнение реализует кнопка Start Server. По этой кнопке запускаются два потока. Один поток работает на ввод данных от клиента, второй — на вывод. Выход из сервера реализуется по кнопке Exit.

Рис. 2.15. Окно приложения сервера

Текст потока, работающего на вывод, помещен далее (листинг 2.24). Этот поток выдает на сторону клиента результат выборки из базы данных по принятому SQL-запросу. Факт формирования результата выборки отслеживается с помощью переменной act. Строка с результатом выборки (ser2) формируется в другом потоке сервера, работающем на ввод. Объявление сокета и подключение к нему должны быть ясны из листинга 2,24 (см, также главу 2).

\ Листинг 2.24. Поток сервера server2, работающий на вывод

class server2 extends Thread

ServerSocket serverr;

Socket outserver;

static String ser2="accepted from 2526"; // Порт 2526

// назначен здесь // для вывода из сервера PrintStream serverprint; // Объявляем потоковый класс для

// вывода

int nu=l;

{

yield(); // Эта команда позволяет пропустить вперед // выполнение более приоритетных потоков

try

{

serverr=new ServerSocket(2526); // Назначаем сокет для

// вывода

}

catch(Exception err)

{ServerBD.lb.setText("B2ErrorSocket:"+err) ; } while(ServerBD.act==false)

// статическая переменная act определяет (act=true) наличие // сформированного результата выборки по команде SQL {

try

{

yield () ;

ServerBD.lb.setText("Is waiting:"+nu); sleep(1000); nu+=l;}

catch(Exception err)

{ServerBD.lb.setText("H2ErrorSleep:"+err);}

}

ServerBD.lb.setText("Sending answer to client"); yield () ; while(true)

{

try

{

// С этого места реализуется вывод информации из сервера // через сокет

outserver=serverr.accept(); // Ожидание подключения

// клиента

yield () ;

if (outserver !=null)

{

serverprint=new PrintStream(outserver.getOutputStream());

serverprint.println(ser2); // Выводится на сторону

// клиента строка

ServerBD.act=false; // Вывод завершен. Сервер ожидает

// новый сформированный результат для вывода

}

}

catch(Exception err)

{

ServerBD.lb.setText("A2ConnectError:"+err);

}

yield () ;

}

}

}

Из сервера передается обратно клиенту строка с именем ser2, формируемая в первом потоке. Поток сервера, принимающий SQL-запрос от клиента, выполняется в классе public class ServerBD extends Frame implements Runnable. Рассмотрим ПОТОК сервера, работающий на ввод, а начнем с его основного метода run().

public void run()

{

lb.setText("Server is launched"); try {

server=new ServerSocket(2525); // Создается новое гнездо

// для прослушивания

}

catch(Exception err)

{ lb.setText("BErrorSocket:"+err);}

try

{

db=DriverManager.getConnection(bdurl); // Получаем // соединение с базой данных, определенной через // переменную String bdurl="jdbc:odbc:vfp"

}

catch(Exception errl)

{ lb.setText("CC_DBconnectErr:"+errl);} try

{ sqlst=db.createStatement(); }// Создаем команду SQL catch(Exception err2)

{lb.setText("FError:"+err2);} while(true)

{

try

{

inserver=server.accept(); // Подключаемся к клиенту if (inserver !=null)

{

// Создаем потоковую переменную для ввода из сокета: serverinput=new

DataInputStream(inserver.getInputStream ()) ; lb.setText(serverinput.readLine());

// Принятый SQL-запрос отображаем в текстовом поле // с именем lb

}

}

catch(Exception err)

{ lb.setText("A Connection Error:"+err); continue;} tar.setText(lb.getText());

String str_sql=lb.getText(); // В переменной str_sql

// помещаем текст SQL-запроса int priz=4; // Переменная priz определяет

// распознанный тип SQL-запроса

String

swork=((str_sql.trim()).substring(0,6)).toUpperCase();

// Вьщеляем подстроку строки SQL запроса длиной 7 символов, // имея в виду, что SQL-команда одна из: SELECT, CREATE,

// UPDATE, INSERT (6 символов + 1 символ пробела) if (swork.equals("SELECT") )

{ priz=l;}

else // Устанавливаем переменную priz в зависимости // от принятой SQL-команды if (swork.equals("CREATE"))

{priz=2;} else priz=3;

try

{

// Переменная priz определяет, какая SQL-команда получена // (см. по тексту) switch(priz)

{

case 1:

// Если команда SELECT, то она выполняется так: rs= sqlst.executeQuery(str_sql); lb.setText("1:SELECT");

// processing the results of selection //обработка результатов выборки: tar.setText("");

int colsnumber=rs.getMetaData().getColumnCount();

/ Определяем число выбранных столбцов в результирующем // наборе;

String ss=""; // Переменная ss служит для формирования // записей для отправки клиенту while(rs.next()) // в rs — очередная запись из базы / / данных

tar.append("\n");

for (i=l ;i<=colsnumber;i++)

{

// Определяем тип столбца из rs: int coltype=rs.getMetaData().getColumnType(i); if (coltype==l) // Тип 1 соответствует строковому {

ss=ss+" "+rs.getString(i); // Читаем содержимое i-ro

// столбца строкового типа

}

else

if (coltype==2) // Тип 2 соответствует целому числу { ss=ss+" "+rs.getInt(i); }

}

tar.append(ss); // Считанные значения добавляем в // текстовую область с именем tar server2.ser2=ss; // Этим оператором формируется строка // ser2, передаваемая обратно клиенту из потока сервера, // работающего на вывод

gg=llll;

}

rs.close();

lb.setText(server2.ser2) ; act=true;

Thread.yield() ;

break;

case 2:

sqlst.execute(str_sql); // Команда execute() выполняется // при создании таблицы по SQL-запросу CREATE TABLE lb. setText ("2 :CREATE") ; break; case 3:

sqlst.executeUpdate(str_sql); // Команда на обновление

// базы данных

lb.setText("3:INSERT/UPDATE");

break;

default:

tar.setText("NONO"); break;

}

}

catch(Exception errl)

{

lb.setText("CH_DBconnectErr:"+errl); tar.setText(str_sql);

}

Далее (листинг 2.25) приводится полный текст приложения сервера, снабженный необходимыми комментариями.

j Листинг 2.25. Полный текст приложения сервера

import java.awt.*; import java.io.*; import java.sql.*; import java.net.*;

//Серверная часть, работающая на вывод, была разобрана ранее, class server2 extends Thread

ServerSocket serverr;

Socket outserver; // Сокет для вывода результата обработки // запроса

static String ser2="accepted from 2526";

PrintStream serverprint; // Потоковая переменная для вывода

// в сокет

int nu=l;

public void run() // Главный метод потока

yield () ; try {

serverr=new ServerSocket(2526); // Для вывода используем

// порт с номером 2526

}

catch(Exception err)

{ ServerBD.lb.setText("B2ErrorSocket:"+err);} while(ServerBD.act==false) // "холостой ход", пока

// act=false

{

try

{

yield () ;

ServerBD.lb.setText("Is waiting:"+nu); sleep(1000); nu+=l;

}

catch(Exception err)

{ServerBD.lb.setText("H2ErrorSleep:"+err);}

}

ServerBD.lb.setText("Sending answer to client"); yield () ; while(true)

{

try

{

outserver=serverr.accept(); // Ждем подключения клиента

// для отсылки ему строки

yield () ;

if (outserver !=null)

{ serverprint=new

PrintStream(outserver.getOutputStream());

serverprint.println(ser2); // Отсьшка строки ser2

// клиенту

ServerBD.act=false;

}

}

catch(Exception err)

{ServerBD.lb.setText("A2ConnectError:"+err);} yield () ;

}

}

}

// Класс сервера, содержащий поток, работающий на ввод public class ServerBD extends Frame implements Runnable {

int i ;

static boolean act=false; // Переменная act=true, если

// сформирован результат выборки Thread serverthread; // Объявление потока сервера,

// работающего на ввод

ServerSocket server;

String bdurl="jdbc:odbc:vfp"; // Строка для установления

// соединения // с базой данных Socket inserver; // Сокет для ввода SQL-запроса от клиента DataInputStream serverinput; // Объявление потоковой

// переменной для чтения данных Button btn_exit=new Button("Exit Server"); // Кнопка для

// завершения // приложения сервера Button btn_launch=new Button("StartServer"); // Кнопка для

// запуска // потоков сервера static Label lb=new Label("Server is Sleeping");

static TextArea tar=new TextArea(); // Текстовая область // для размещения результатов выборки Connection db; // Переменная соединения Statement sqlst; // Переменная для SQL-запроса ResultSet rs; // Результирующий набор команды Select

ServerBD() // Конструктор, формирующий окно приложения // сервера

{

add(btn_exit);

add(lb);

add(btn_launch); add (tar) ; setLayout(null) ;

setBackground(new Color(50,20,150)); lb.setForeground(Color.yellow); btn_exit.setBounds(20,20,100, 20); btn_launch.setBounds(130,20,100,20); lb.setBounds(20,60,450,20); tar.setBounds(20,80,450,200) ; try {

// Подключение интерфейса JDBC-ODBC:

Class.forName("sun.j dbc.odbc.JdbcOdbcDriver");

}

catch(Exception err)

{lb.setText("ClassForNameErr"+err);}

}

public boolean action(Event evt, Object arg)

// Обработка событий от программных кнопок {

if (evt.target==btn_exit)

{ System.exit(0); return true; } else

if (evt.target==btn_launch) // Событие от кнопки для

// запуска потоков

{

try

{

serverthread= new Thread(this); // Создаем поток

// сервера для ввода serverthread.start(); // Запускаем поток сервера для

// ввода

server2 serv2 =new server2(); // Создаем поток сервера

// для вывода

serv2.start(); // Запускаем поток сервера для вывода lb.setText("Server Thread is Activated");

}

catch(Exception err)

{lb.setText("ERROR in Thread:"+err);} return true;

}

else

{ return false; }

}

public void run() // Главный метод потока сервера для ввода {

lb.setText("Server is launched"); try {

server=new ServerSocket(2525); // Создаем сокет для ввода

// SQL-запроса на базе // порта 2525

}

catch(Exception err)

{lb.setText("BErrorSocket:"+err);}

try

db=DriverManager.getConnection(bdurl); // Попытка // установить соединение с базой данных для выполнения // принятого SQL-запроса

catch(Exception errl)

{ lb.setText("CC_DBconnectErr:"+errl) ; } try {

sqlst=db.createStatement();//Создаем команду SQL

}

catch(Exception err2)

{ lb.setText("FError:"+err2); }

while(true)

{

try

{

inserver=server.accept(); // Ожидаем передачи от клиента

// SQL-запроса

if (inserver !=null)

{

serverinput=new

DataInputStream(inserver.getInputStream()); lb.setText(serverinput.readLine()); // Отображаем

// принятую строку // запроса // в текстовом поле lb

}

}

catch(Exception err)

{lb.setText("А ConnectError:"+err); continue;} tar.setText(lb.getText()) ;

String str_sql=lb.getText(); // В переменную str_sql

// помещаем текст SQL-запроса

int priz=4;

String

swork=((str_sql.trim()).substring(0,6)).toUpperCase();

// Вьщеляем подстроку swork, содержащую код SQL-команды,

// из строки запроса. if (swork.equals("SELECT"))

{ // Проверяем код команды и, соответственно,

// формируем переменную priz priz=l;

}

else

if (swork.equals("CREATE")) {priz=2;} else priz=3; try {

switch(priz)

{

case 1:

rs= sqlst.executeQuery(str_sql) ; // Формируем

// результирующий // набор для команды

SELECT

lb.setText("1:SELECT");

// Обработка результирующего набора tar.setText("");

int colsnumber=rs.getMetaData().getColumnCount();

// В colsnumber заносим число столбцов набора String ss=""; // В строку ss заносим содержимое полей // текущей записи набора rs while(rs.next()) // Обработка записей набора rs {

tar.append("\n"); // Записи отделяются символом // конца строки //"\n" for (i=l ;i<=colsnumber;i++)

int coltype=rs.getMetaData().getColumnType(i);

// B coltype — тип столбца

// Тип столбца таблицы определяет способ чтения // его содержимого

if (coltype==l) // Столбец имеет строковый тип {

ss=ss+" "+rs.getString(i); // В ss записываем

// строковое // значение из столбца

}

else

if (coltype==2) // Столбец имеет целочисленный тип {

ss=ss+" "+rs.getInt(i); // В ss записываем целое

// значение из столбца

}

}

tar.append(ss);

server2.ser2=ss; // Переменная ss с занесенным в нее // набором rs передается обратно // на сторону клиента

ss="";

}

rs.close();

lb.setText(server2.ser2) ; act=true;

Thread.yield() ; break;

case 2: // Команда SQL есть CREATE TABLE sqlst.execute(str_sql);//BbnionHeHHe команды CREATE lb. setText ("2 :CREATE") ; break;

case 3: / / Остальные команды SQL проходят в этом // варианте оператора case sqlst.executeUpdate(str_sql); // Выполнение команд,

// отличных от // SELECT, CREATE lb.setText("3:INSERT/UPDATE"); break; default:

tar.setText("No valid SQL code"); break;

}

}

catch(Exception errl)

{

lb.setText("CH_DBconnectErr:"+errl); tar.setText(str_sql);

}

}

}

public static void main(String args[])

{

ServerBD sbd=new ServerBD(); sbd.resize(500,360); sbd.show();

}

}

Рассмотрение серверной части закончено. В приложении к этому занятию мы рассмотрим кратко SQL-запросы. Переходим к стороне клиента, окно которого прдставлно на рис. 2.16.

Кнопки в окне клиента позволяют вставить в окно редактирования каркас SQL-запроса и затем сформировать его целиком. Результат запроса инициируется кнопкой ЕХЕситв QUERY. Пример представления результата дает следующее окно (рис. 2.17).

Рис. 2.16. Окно клиента

Рис. 2.17. Пример результата SQL-запроса

Аналогично серверу, клиентская программа реализует два потока. Первый поток служит для передачи SQL-запроса в сервер. Второй поток принимает результат работы сервера. Поток клиента для передачи запроса серверу имеет такой вид:

// Поток клиента на вывод — передача серверу SQL-запроса public void run() // Главный метод потока

try

clienttransmit=new Socket("127.0.0.1",2525); // Эта команда // и обеспечивает сокетное соединение с сервером // Получаем выходной поток для клиента: clientprint=new

PrintStream(clienttransmit.getOutputStream()) ; clientprint.println(str_query); // Передаем SQL-запрос

// серверу

lbl.setText("Query is sent To Server"); clientprint.flush();

clienttransmit.close(); // Закрываем сокетное соединение

// со стороны клиента client2= new Client2BD();

client2.start(); // Запускаем поток клиента на ввод // результата от сервера

catch(Exception err)

lbl.setText("The Error in connection:"+err);

Теперь приведем полный текст программы клиента с комментариями (листинг 2.26).

Листинг 2.26. Полный текст приложения клиента

import java.awt.*; import java.lang.*; import java.net.*; import java.io.*;

class DialogBD extends Frame // Здесь создается диалоговое // окно клиента для подтверждения выбранного действия // на стороне клиента

Button btn_ok=new Button("Click if YES");

Button btn_no=new Button("Click if N0");

Label lb=new Label("CONFIRM THE SOLUTION");

Event dialogevent;

ClientBD dialogBD; // Объявляется класс диалогового окна,

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

DialogBD(Event evt, ClientBD cldbcopy)

{

super("DESICIONDIALOG");

dialogevent=evt; dialogBD=cldbcopy;

Font fnt=new Font("Courier",Font.BOLD,18);

lb.setFont(fnt);

lb.setForeground(new Color(100,20,250)); add(btn_ok); add(btn_no); add(lb);

setLayout(null); btn_ok.setBounds(20,60,100,20); btn_no.setBounds(120,60,100,20); lb.setBounds(10,15,250,40) ;

}

public void spaint()

{

setBackground(new Color(77,150,120));

}

public boolean action(Event evt, Object arg)

{

if (evt.target==btn_ok)

{

ClientBD.Solution=l; // Переменная Solution=l, если выйти // из приложения клиента dispose(); // Команда закрытия окна диалога dialogBD.procaction(dialogevent); return true;

}

else

if (evt.target==btn_no)

ClientBD.Solution=O;

dispose(); // Команда закрытия окна диалога dialogBD.procaction(dialogevent); return true;

}

else return false;

}

}

class Client2BD extends Thread {

Socket clientreceiver;

// Поток клиента для ввода данных — результата SQL-запроса к // серверу

DataInputStream clientinput=null; public void run()

{

try

{

clientreceiver=new Socket("127.0.0.1",2526); // Создаем

// сокет // для ввода

// Потоковая переменная для ввода: clientinput=new

DataInputStream(clientreceiver.getInputStream());

String ssr=clientinput.readLine(); // Чтение результата,

// возвращенного сервером, из сокета ClientBD.lbl.setText("Answer from Server"); ClientBD.ta.setText(ssr); // Вывод ответа сервера

// в текстовое окно

}

catch(Exception err)

{ ClientBD.lbl.setText("The Error in connection:"+err); }

// Основное окно клиента

public class ClientBD extends Frame implements Runnable {

Socket с1ienttransmit; // Сокет для вывода

PrintStream clientprint=null; // Потоковый класс для вывода String str_query=""; // Строка запроса String sss;

static int Solution=2;

ClientBD cldbcopy;

Client2BD client2;

// Все эти элементы нетрудно увидеть в окне клиента Button btn_exec=new Button("EXECUTE QUERY"); // Основная // кнопка для посылки запроса на сервер

Button btn_create=new Button("CREATE TABLE"); // Формирует

// каркас // команды

CREATE

Button btn_delete=new Button("DELETE"); // Формирует каркас

// команды DELETE Button btn_write=new Button("WRITE RECORD");

Button btn_update=new Button("UPDATE"); // Формирует каркас

// команды UPDATE

Button btn_find=new Button("SELECT"); // Формирует каркас

// команды SELECT Button btn_clear=new Button("CLEAR"); // Очищает текстовую

// область

Button btn_exit=new Button("EXIT"); // Запуск диалога

// на выход из приложения // клиента

static TextArea ta= new TextArea();

Thread clientthread; // Поток клиента на ввод static Label lbl=new Label("");

public ClientBD() // Конструктор клиента инициализирует // интерфейсную часть

super("JAVACLIENTINTERFACE");

cldbcopy=this; setLayout(null); add(btn_exec); add(btn_create); add(btn_delete) ; add(btn_write); add(btn_update); add(btn_find); add(btn_clear); add(btn_exit); add(lbl); add (ta) ;

btn_exec.setBounds(0,20,600, 20); btn_create.setBounds(0,40,100,20); btn_delete.setBounds(100, 4 0,100, 20) ; btn_write.setBounds(200,40,100, 20) ; btn_update.setBounds(300, 4 0,100, 20); btn_find.setBounds(400,40,100, 20); btn_clear.setBounds(500, 40,100, 20) ; btn_exit.setBounds(0, 60,100, 20);

1Ы. setBounds (100, 60, 520, 20) ; ta.setBounds(0,80,600,320); ta.setEditable(true);

}

// Программирование реакции на нажатие кнопок public boolean action(Event evt,Object arg)

{

if (evt.target instanceof Button) // Независимо от того, // какая кнопка нажимается, запускается окно диалога – // объект класса DialogBD {

DialogBD dlg=new DialogBD(evt, cldbcopy);

// Конструктору DialogBD передается объект-событиее^ и // объект-копия // класса ClientBD

dlg.resize(300,100); // Задание параметров диалогового // окна

dlg.spaint(); // Установка фонового цвета диалогового окна dlg.move(200,200); // Изменение позиции на экране // диалогового окна dlg.show(); // Отображение диалогового окна return true;

}

return false;

}

// После закрытия окна диалога, если нет завершения клиента, // запускается метод procaction() для продолжения обработки // события evt в соответствии с принятым решением Solution public boolean procaction(Event evt)

{

// Solution==l означает, что действие в диалоге подтверждено if((evt.target == btn_exit)&&(Solution==l))

{

System.exit(0); // Завершение клиента return true;

}

else

if ((evt.target==btn_exec)&&(Solution==l))

{

str_query=ta.getText(); if (clientthread ==null)

{

// Создание потока клиента на вывод clientthread= new Thread(this);

clientthread.start(); // Запускается поток клиента на // вывод текста SQL-запроса // на сервер

else

{

1Ы.setText("Cannot run At the moment");

// Предупреждающее сообщение; Требуется повторить

clientthread=null;

}

Solution=2; return true;

}

else

if((evt.target==btn_create)&&(Solution==l)) // Выводится // шаблон (каркас) команды CREATE TABLE

{

String str_tl=ta.getText(); int len_str=str_t1.length(); ta.replaceText("",0,len_str);

String str_create="CREATE TABLE ?TABLENAME(?PAR1 char(50), "+

"?PAR2 char(50))\n"+"//insert real values instead of ??" ■

// Строка str_create содержит каркас команды CREATE // TABLE

ta.appendText(str_create);

Solution=2; return true;

}

else

if ((evt.target== btn_delete)&&(Solution==l))

String str_tl=ta.getText(); int len_str=str_tl.length() ; ta.replaceText("",0,len_str);

String str_delete="DELETE WHERE ?CONDITION?n"+

"// insert a CONDITION instead of ??"; // Шаблон // команда DELETE ta.appendText(str_delete);

Solution=2; return true;

}

else

if ((evt.target==btn_write)&&(Solution==l))

{

String str_tl=ta.getText() ; int len_str=str_t1.length();

ta.replaceText("",0,len_str); // Вьшодится шаблон

// команда INSERT

String str_insert="INSERT INTO ?TABLE VALUES(?PAR1,?PAR2,…)\n"+

"// insert real values instead of ??";

ta.appendText(str_insert);

Solution=2;

return true;

}

else

if ((evt.target==btn_update)&&(Solution==l))

{

String str_tl=ta.getText(); int len_str=str_t1.length();

ta.replaceText("",0,len_str); // Вьшодится шаблон

// команды UPDATE

String str_update="UPDATE ?TABLE SET ?PAR=?VAL WHERE ?CONDIT\n"+

"//insert NAME and VALUE of PAR and set a CONDITION ??" ■

ta.appendText(str_update);

Solution=2; return true;

else

if ((evt.target==btn_find)&&(Solution==l))

{

String str_tl=ta.getText(); int len_str=str_t1.length();

ta.replaceText("",0,len_str); // Выводится шаблон

// команда SELECT

String str_select="SELECT * FROM ?TABLE WHERE ?CONDITION))\n"+

"// set Table Name and CONDITION marked with ??"; ta.appendText(str_select);

Solution=2; return true;

}

else

if ((evt.target==btn_clear)&&(Solution==l))

{

String str_tl=ta.getText(); int len_str=str_tl.length(); ta.replaceText("",0,len_str);

Solution=2; return true;

}

else

{

Solution=2; return false;

}

}

public void run()

try

// Создается сокетное соединение на вывод SQL-запроса на // сервер

clienttransmit=new Socket("127.0.0.1",2525); clientprint=new

PrintStream(clienttransmit.getOutputStream ()) ; clientprint.println(str_query); // Вьшод запроса // реализуется оберточным классом PrintStream,

// осуществляющим вывод строк

1Ы.setText("Query is sent То Server"); clientprint.flush(); clienttransmit.close() ; client2= new Client2BD();

client2.start(); // Запускается поток клиента // на ввод ответа от сервера

}

catch(Exception err)

{ 1Ы.setText("The Error in connection:"+err); }

}

public static void main(String args[])

{

ClientBD cldb=new ClientBD(); cldb.resize(600,400); cldb.show();

}

}

Отдельный класс используется для создания диалогового окна, в котором выдается запрос на подтверждение действия:

class DialogBD extends Frame {

Button btn_ok=new Button("Click if YES"); // Кнопка для

// подтверждения действия Button btn_no=new Button("Click if NO"); // Кнопка для

// отмены действия Label lb=new Label("CONFIRM THE SOLUTION");

Event dialogevent; // Событие dialogevent держит копию

// события evt основного окна клиента

ClientBD dialogBD;

DialogBD(Event evt, ClientBD cldbcopy)

{

super("DESICIONDIALOG");

dialogevent=evt; // dialogevent и evt – одно и то же событие dialogBD=cldbcopy; // Переменная dialogBD относится к классу // ClientBD Font fnt=new Font("Courier",Font.BOLD,18); lb.setFont(fnt);

lb.setForeground(new Color(100,20,250)); add(btn_ok); add(btn_no); add(lb);

setLayout(null); btn_ok.setBounds(20,60,100,20); btn_no.setBounds(120,60,100,20); lb.setBounds(10,15,250,40) ;

}

public void spaint()

{

setBackground(new Color(77,150,120));

}

public boolean action(Event evt, Object arg)

{

if (evt.target==btn_ok)

{

ClientBD.Solution=l; // Статическая переменная Solution // определяет выбранное действие в диалоге и // обрабатывается в основном классе клиента в методе // procaction() dispose();

dialogBD.procaction(dialogevent); // Метод procaction()

// обрабатывает событие после закрытия диалога

return true;

else

if (evt.target==btn_no)

{

ClientBD.Solution=O;

dispose();

dialogBD.procaction(dialogevent); return true;

}

else return false;

}

}

Источник: Герман О. B., Герман Ю. О., Программирование на Java и C# для студента. — СПб.: БХВ-Петербург, 2005. — 512 c.: ил.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100