Логин:   Пароль:




Новости
Рассылки
Форум
Поиск


Java
- Апплеты
- Вопрос-ответ
- Классы
- Примеры
- Руководства
- Статьи
- IDE
- Словарь терминов
- Скачать

Мобильная Java
- Игры
- Примеры
- Статьи
- WAP, WML и пр.

JavaScript
- Вопрос-ответ
- Примеры
- Статьи

Веб-мастеринг
- HTML
- CSS
- SSI

Разминка для ума
Проекты
Книги
Ссылки
Программы
Юмор :)




Rambler's Top100

РассылкиАрхив Java programmingВыпуск 18-й

Java programming выпуск 18-й

Здравствуйте дорогие читатели!

Начинающим

Условные операторы

if-else

В обобщенной форме этот оператор записывается следующим образом:
if (логическое выражение) оператор1; [ else оператор2;]

Раздел else необязателен. На месте любого из операторов может сто­ять составной оператор, заключенный в фигурные скобки. Логическое выражение — это любое выражение, возвращающее значение типа boolean.

Вот посмотрите небольшую программку определения возрастной категории, используются операторы if-else:


class IfElseClass
{
 public static void main(String args[])
 {
  int age=6;
  if(age>=0&&age;<7) System.out.println("You very young");
  else if(age>=7&&age;<18) System.out.println("You young");
  else if(age>=18&&age;<50) System.out.println("You adult");
  else if(age>=50&&age;<80) System.out.println("You old");
  else if(age>=80&&age;<=180) System.out.println("You very old");
  else if(age>180) System.out.println("You deadmen");
  else System.out.println("Wrong age");
 }
}  

После выполнения программы вы должны получить следующий результат:
You very young

break

В языке Java отсутствует оператор goto. Для того, чтобы в некоторых случаях заменять goto, в Java предусмотрен оператор break. Этот оператор сообщает исполняющей среде, что следует прекратить выполнение именованного блока и пере­дать управление оператору, следующему за данным блоком. Для имено­вания блоков в языке Java используются метки. Оператор break при работе с циклами и в операторах switch может использоваться без метки. В таком случае подразумевается выход из текущего блока.

Например, в следующей программе имеется три вложенных блока, и у каждого своя уникальная метка. Оператор break, стоящий во внутреннем блоке, вызывает переход на оператор, следующий за бло­ком b. При этом пропускаются два оператора println.


class Break
{ 
public static void main(String args[])
{ 
 boolean t = true; 
 a:      
  { 
   b:
    { 
     c:
      { 
       System.out.println("Before the break"); // Перед break
       if (t) break b;
       System.out.println("This won't execute");  // Не будет выполнено
      }
      System.out.println("This won't execute"); // Не будет выполнено
    }
    System.out.println("This is after b"); //После b
  }
 }
}
В результате исполнения программы вы получите следующий результат:
Before the break
This is after b

switch

Оператор switch обеспечивает ясный способ переключения между раз­личными частями программного кода в зависимости от значения одной переменной или выражения. Общая форма этого оператора такова:
switch ( выражение )
{
case значение1:
break;
case значение2:
break;
case значением:
break;
default:
}

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

Если же значению выражения не соответ­ствует ни один из операторов case, управление передается коду, распо­ложенному после ключевого слова default. Отметим, что оператор default необязателен. В случае, когда ни один из операторов case не соответст­вует значению выражения и в switch отсутствует оператор default вы­полнение программы продолжается с оператора, следующего за операто­ром switch.

Внутри оператора switch break без метки при­водит к передаче управления на код, стоящий после оператора switch. Если break отсутствует, после текущего раздела case будет выполняться следующий. Иногда бы­вает удобно иметь в операторе switch несколько смежных разделов case, не разделенных оператором break.

В следующей программе определим к какому сезону относится месяц:


class SwitchClass
{
 public static void main(String args[])
 {
  int month = 4;
  String season;
  switch (month)
  {
   case 12:
   case 1:
   case 2:
   season = "Winter";
   break;
   case 3:
   case 4:
   case 5:
   season = "Spring";
   break;
   case 6:
   case 7:
   case 8:
   season = "Summer";
   break;
   case 9:
   case 10:
   case 11:
   season = "Autumn";
   break;
   default:
   season = "Bogus Month";
  } 
  System.out.println("April is in the " + season + "."); 
 }
} 

return

Оператор return приводит к немедленному завершению работы и передаче управления коду, вызвавшему метод.

Рассмотрим пример, иллюстрирующий использование оператора return для немедленного возврата управления, в данном случае — исполняющей среде Java.


class ReturnDemo
{
 public static void main(String args[])
 {
  boolean t = true;
  System.out.println("Before the return"); //Перед оператором return
  if (t) return;
  System.out.println("This won't execute"); //Это не будет выполнено
 }
}

Замечание: Зачем в этом примере использован оператор if (t)? Дело в том, не будь этого оператора, транслятор Java догадался бы, что последний оператор println никогда не будет выполнен. Такие случаи в Java считаются ошибками, поэтому без оператора if оттранслировать этот пример нам бы не удалось.

В следующем номере мы рассмотрим циклы.

Тема "на заказ"

Многопоточность (продолжение)

Синхронизация потоков

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

Однопоточная программа, такая, например, как программа MS-DOS, при запуске получает в монопольное распоряжение все ресурсы компьютера. Так как в однопоточной системе существует только один процесс, он использует эти ресурсы в той последовательности, которая соответствует логике работы программы. Процессы и потоки, работающие одновременно в многопоточной системе, могут пытаться обращаться одновременно к одним и тем же ресурсам, что может привести к неправильной работе приложений.

Поясним это на наглядном примере.

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

Клиент реализуется классом наследуемым от класса Thread:


package samplethread;

public class ClientAccount extends Thread
{
 StartFrame moneyFrame;
 int money=0;
 public ClientAccount(int money, StartFrame moneyFrame)
 {
  this.moneyFrame=moneyFrame;
  this.money=money;
 }
 public void run()
 {
  while(true)
  {
   moneyFrame.cMoney(money);
  }
 }
}

В конструкторе мы получаем сумму которую мы хотим снять или положить на счёт (если сумм положительна то положить, если отрицательно - снять), и форму в которой нам доступен метод cMoney(money) реализующий доступ к счету.

Форма содержащая счёт и метод cMoney(money) будет представляться следующим классом:


package samplethread;

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

public class StartFrame extends JFrame
{
 XYLayout layout = new XYLayout();
 JTextField mainAccount = new JTextField("100000");
 JTextField comeMoney = new JTextField("0");
 JLabel jLabel1 = new JLabel("Сумма на счету:");
 JLabel jLabel2 = new JLabel("Приход:");
 JButton jb = new JButton("Exit");
 JButton jb2 = new JButton("Start");
 ClientAccount ca1;
 ClientAccount ca2;
 ClientAccount ca3;
 JTextArea errorTextArea1 = new JTextArea();
 public StartFrame()
 {
  enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  try
  {
   jbInit();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
 private void jbInit() throws Exception
 {
  this.setSize(new Dimension(320, 180));
  this.setTitle("Sample no synchronized thread");
  this.getContentPane().setLayout(layout);
  mainAccount.setEditable(false);
  comeMoney.setEditable(false);
  jb.addMouseListener(new java.awt.event.MouseAdapter()
  {
   public void mouseClicked(MouseEvent e)
   {
    jbCM();
   }
  });
  jb2.addMouseListener(new java.awt.event.MouseAdapter()
  {
   public void mouseClicked(MouseEvent e)
   {
    jb2CM(e);
   }
  });
  this.setResizable(false);
  this.getContentPane().add(jLabel1, new XYConstraints(5, 5,100, 20));
  this.getContentPane().add(mainAccount, new XYConstraints(120, 5, 100, 20));
  this.getContentPane().add(jLabel2, new XYConstraints(5, 50, 100, 20));
  this.getContentPane().add(comeMoney, new XYConstraints(120, 50, 100, 20));
  this.getContentPane().add(jb, new XYConstraints(240, 40, 60, 20));
  this.getContentPane().add(jb2,  new XYConstraints(240, 10, 60, 20));
  this.getContentPane().add(errorTextArea1,  new XYConstraints(5, 80, 300, 60));
 }
 protected void processWindowEvent(WindowEvent e)
 {
  super.processWindowEvent(e);
  if (e.getID() == WindowEvent.WINDOW_CLOSING)
  {
   jbCM();
  }
 }
 public void jb2CM(MouseEvent e)
 {
  ca1=new ClientAccount(1000,this);
  ca1.start();
  ca2=new ClientAccount(-2000,this);
  ca2.start();
  ca3=new ClientAccount(3000,this);
  ca3.start();
 }
 public void jbCM()
 {
  ca1=null;
  ca2=null;
  ca3=null;
  System.exit(0);
 }
 public void cMoney(int money)
 {
  comeMoney.setText(""+money);
  try
  {
   Integer mm= new Integer(mainAccount.getText());
   int m=mm.intValue()+money;
   mainAccount.setText(""+m);
  }
  catch(Exception e)
  {
   errorTextArea1.setText(errorTextArea1.getLineCount()+" Error: 
Одновременный доступ к счету: " + e + "\n");
   //System.out.println("Error: Одновременный доступ к счету: "+ e);
  }
 }
}

По нажатии кнопочки jb создаём три новых потока (в методе jb2CM(MouseEvent e)).

По нажатии кнопочки jb2 завершаем работу потоков (в методе jbCM()).

В методе cMoney(int money), который вызывается потоками-клиентами, мы получаем сумму, выводим её в текстовое поле "приход", и прибавляем её к основному счету.

Как вы могли заметить в методе cMoney(int money) все основные операции находятся в блоке try, т.е. обрабатываются на возможность появления исключительной ситуации. Это связано с тем что при попытке одновременного доступа потоков к методу будет появляться ошибка преобразования форматов, так как в текстовое поле mainAccount будут записываться одновременно разные данные.

Можете посмотреть это запустив приложение из данного jar-архива.

Для того чтобы избежать этого необходимо объявить наш метод как synchronized, сделав его синхронизированным:


public synchronized void cMoney(int money) 

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

Использование синхронизированных методов - достаточно простой способ синхронизации потоков, обращающихся к общим критическим ресурсам.

Не обязательно синхронизовать весь метод - можно выполнить синхронизацию только критичного фрагмента кода:


synchronized(mainAccount)
{
 Integer mm= new Integer(mainAccount.getText());
 int m=mm.intValue()+money;
 mainAccount.setText(""+m);
}

Вот теперь посмотрите как работает приложение запустив его из данного jar-архива.

В следующем номере ещё поговорим о потоках и попробуем написать более функциональную программу.

Вопрос - ответ

Вопрос: Требуется загрузить в BufferedImage изображение из указаного файла после обработки сохранить на диск в указаный файл.
Nikolay

Ответ: Вот метод позволяющий сохранять BufferedImage в jpg файл:


import java.io.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;
  
 /*
 ....................
 */
 
 public void saveImageAsJPEG(Image img, String fileName, ImageObserver imgObs)
 {
  int w=img.getWidth(this);
  int h=img.getHeight(this);
  BufferedImage bimg = new BufferedImage(w,h,BufferedImage.TYPE_3BYTE_BGR);
  bimg.getGraphics().drawImage(img,0,0,imgObs);
  
  /*
  ..........
  Здесь вставляете код обработки изображения.
  ..........
  */
  
  try
  {
   FileOutputStream fos = new FileOutputStream(fileName);
   JPEGImageEncoder jc= JPEGCodec.createJPEGEncoder(fos);
   jc.encode(bimg);
   fos.close();
  }
  catch(IOException ioe)
  {
  }
 }

Вопрос:

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

Я решил данный эелемент сделать на Swing, используя ScrollPane(,,,,) и JTextArea() у меня это работает. Но когда я хочу этот элемент вставить в CardLayout() как панель или на какую-нибудь другую панель то эффекта никакого!!!!
bob

Ответ: Если я вас правильно понял то работающий пример помещаю в раздел "Программный код…"

Вопрос: Как можно использовать RadioButton в меню (JMenu) и каким образом я могу задать горячею клавишу.
Роман

Ответ: Посмотрите пример создания меню

Вопрос: Где можно скачать JAVA и сколько занимает оригинал JAVA.
Diesel_matrix

Ответ: Прошу перед тем как задать вопрос прочитать FAQ по разделу:
FAQ по Java ( Ответ на ваш вопрост здесь).
FAQ по JavaScript.

Программный код…


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

public class Frame1 extends JFrame
{
 JPanel contentPane;
 JPanel panel1 = new JPanel();
 JPanel panel2 = new JPanel();
 JPanel panel3 = new JPanel();
 JPanel panel2_1 = new JPanel();
 JPanel panel2_2 = new JPanel();
 JPanel panel2_3 = new JPanel();
 JPanel panel4 = new JPanel();
 JScrollPane jScrollPane1 = new JScrollPane();
 JTextArea jTextArea1 = new JTextArea();
 BorderLayout borderLayout1 = new BorderLayout();
 BorderLayout borderLayout2 = new BorderLayout();
 BorderLayout borderLayout3 = new BorderLayout();
 CardLayout cardLayout1 = new CardLayout();
 public Frame1()
 {
  enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  try
  {
   jbInit();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
 private void jbInit() throws Exception
 {
  contentPane = (JPanel) this.getContentPane();
  this.setSize(new Dimension(400, 300));
  this.setTitle("Frame Title");
  contentPane.setLayout(borderLayout1);
  contentPane.add(panel1, BorderLayout.NORTH);
  contentPane.add(panel2, BorderLayout.CENTER);
  contentPane.add(panel3, BorderLayout.SOUTH);
  panel1.setBackground(Color.red);
  panel2.setBackground(Color.green);
  panel3.setBackground(Color.blue);
  panel2.setLayout(borderLayout2);
  panel2.add(panel2_1, BorderLayout.NORTH);
  panel2.add(panel2_2, BorderLayout.CENTER);
  panel2.add(panel2_3, BorderLayout.SOUTH);
  panel2_2.setLayout(cardLayout1);
  panel2_1.setBackground(new Color(0,200,0));
  panel2_2.setBackground(new Color(0,150,0));
  panel2_3.setBackground(new Color(0,100,0));
  panel2_2.add(panel4,"panel4");
  panel4.setLayout(borderLayout3);
  panel4.add(jScrollPane1);
  jScrollPane1.getViewport().add(jTextArea1);
  jScrollPane1.setAutoscrolls(true);
  jTextArea1.setText("jTextArea1");
 }
 protected void processWindowEvent(WindowEvent e)
 {
  super.processWindowEvent(e);
  if (e.getID() == WindowEvent.WINDOW_CLOSING)
  {
   System.exit(0);
  }
 }
}

Jar-архив

JavaScript

Вопрос: Подскажите пожалуйста, как сделать, чтобы ежемесячно в один и тот же день, например первого числа, происходила бы смена рисунка, причём не выборочно, а по порядку. Т.е. каждому месяцу соответствовал бы свой рисунок.
Валерий

Ответ:


<html;>
<body;>
<img; src="1.gif" name="monthImg">
<script; language="JavaScript">
<!--
d=new Date();
document.monthImg.src=d.getMonth()+".gif";
//-->
</script>
</body>
</html>

Вопрос: Как установить проверку на наличие Java Virtual Machine на клиентском компьютере?
Алексей

Ответ:


navigator.javaEnabled()

Вопрос: Как сделать, что бы все изображениясразу загружались?
Klaus

Ответ: О предворительной загрузки изображений ужеговорилось в в выпуске 7.

Вопрос: Можно ли при помощи JavaScript сделать какие-нибудь фокусы с указателем (мышью)???
Mr.M.A.X

Ответ:

Какие фокусы? Ну смену курсора можно сделать.


<script;>
<!--
function changeCursor(obj,i) 
{
 t=i;
 if(i==0)t="DEFAULT"
 else if(i==1)t="CROSSHAIR"
 else if(i==2)t="HEND"
 else if(i==3)t="MOVE"
 else if(i==4)t="TEXT"
 else if(i==5)t="WAIT"
 obj.style.cursor=t;
}
//-->
</script>

Допустим хотим сменить курсор над ссылкой:


<a; OnMouseOver="changeCursor(this,1)" href="my_file.htm">Ссылка</a>
Пример: Ссылка




Вопросы присылайте на E-mail [email protected] с пометкой "Вопрос по Java".

Жду вопросов и предложений.

Юрий Ладик.

Подписаться на эту рассылку и посмотреть архив можно тут /subs/subs.html


Дэвид Флэнаган
"Java. Справочник"
Подробнее>>
Заказать>>


Р. Р. Мухамедзянов
"Серверные приложения на языке Java"
Подробнее>>
Заказать>>

Узнай о чем ты на самом деле сейчас думаешь тут.


[an error occurred while processing this directive]



Apache Struts 2.0.11
Apache MyFaces Trinidad Core 1.2.3.
Sun переводит мобильные устройства с Java ME на Java SE
Хакерская атака!



Выпуск 29-й
Выпуск 28-й
Выпуск 27-й
Выпуск 26-й
Выпуск 25-й
Выпуск 24-й
Выпуск 23-й
Выпуск 22-й
Выпуск 21-й
Выпуск 20-й
Выпуск 19-й
Выпуск 18-й
Выпуск 17-й
Выпуск 16-й
Выпуск 15-й
Выпуск 14-й
Выпуск 13-й
Выпуск 12-й
Выпуск 11-й
Выпуск 10-й
Выпуск 9-й
Выпуск 8-й
Выпуск 7-й
Выпуск 6-й
Выпуск 5-й
Выпуск 4-й
Выпуск 3-й
Выпуск 2-й
Выпуск 1-й