AgendaScrollPane.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package gui.panels.agenda;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Cursor;
  5. import java.awt.Dimension;
  6. import java.awt.Graphics;
  7. import java.awt.Graphics2D;
  8. import java.awt.Rectangle;
  9. import java.awt.event.MouseAdapter;
  10. import java.awt.event.MouseEvent;
  11. import java.util.ArrayList;
  12. import java.util.Calendar;
  13. import java.util.GregorianCalendar;
  14. import javax.swing.JPanel;
  15. import agenda.Act;
  16. import agenda.Agenda;
  17. @SuppressWarnings("serial")
  18. public class AgendaScrollPane extends JPanel {
  19. ArrayList<AgendaItemShape> agendaItems;
  20. private InfoPane infoPane;
  21. private int clickedItem[];
  22. private int xdifference, ydifference, xspacing;
  23. private final int yspacing = 45;
  24. private final int itempadding = 10;
  25. private final int heightoffset = 100;
  26. GregorianCalendar currentdate;
  27. Agenda agenda;
  28. public AgendaScrollPane(final Agenda agenda, InfoPane pane){
  29. this.infoPane = pane;
  30. this.agenda = agenda;
  31. this.setPreferredSize(new Dimension(600, yspacing*48+heightoffset));
  32. agendaItems = new ArrayList<AgendaItemShape>();
  33. clickedItem = new int[]{-1};
  34. this.addMouseListener(new MouseAdapter() {
  35. @Override
  36. public void mouseReleased(MouseEvent e) {
  37. clickedItem = new int[]{-1};
  38. getClickedItem(e);
  39. }
  40. @Override
  41. public void mousePressed(MouseEvent e) {
  42. clickedItem = getClickedItem(e);
  43. if(clickedItem[0] != -1){
  44. xdifference = -1*((int)agendaItems.get(clickedItem[0]).getX() - e.getX());
  45. ydifference = -1*((int)agendaItems.get(clickedItem[0]).getY() - e.getY())+heightoffset;
  46. infoPane.setMiddleText(agendaItems.get(clickedItem[0]).getName(), agendaItems.get(clickedItem[0]).getAct().toString());
  47. }
  48. repaint();
  49. }
  50. });
  51. this.addMouseMotionListener(new MouseAdapter() {
  52. @Override
  53. public void mouseMoved(MouseEvent e){
  54. getClickedItem(e);
  55. }
  56. @Override
  57. public void mouseDragged(MouseEvent e) {
  58. if(clickedItem[0] != -1){
  59. Rectangle item = agendaItems.get(clickedItem[0]);
  60. if(clickedItem[1] == 2){
  61. item.setSize((int)item.getWidth(), (int)(-1*(item.getY()-e.getY())));
  62. }else{
  63. item.setLocation(e.getX()-xdifference, e.getY()-ydifference);
  64. }
  65. for(AgendaItemShape agendaItem: agendaItems){
  66. if(clickedItem[0] == -1){ //Window is resized, only resize & place the items
  67. agendaItem.setSize(xspacing-itempadding*2, (int) (agendaItem.getHeight()));
  68. agendaItem.setLocation(agendaItem.getRow()*xspacing+itempadding, (int) agendaItem.getY());
  69. }else if(agendaItems.get(clickedItem[0]) == agendaItem){ // The agenda item is moved
  70. if(clickedItem[1] == 0){ //if the agenda item is moved, not resized
  71. if(agendaItem.getX() / xspacing > agenda.getStages().size()-1){ // outside the window on the right
  72. agendaItem.setLocation((int)xspacing*(agenda.getStages().size()-1)+itempadding, (int)agendaItem.getY()+heightoffset);
  73. }else if(agendaItem.getX() / xspacing < 0){ // outside the window on the left
  74. agendaItem.setLocation((int)itempadding, (int)agendaItem.getY()+heightoffset);
  75. }else{ //inside the window, stick it to a stage
  76. agendaItem.setLocation((int) Math.round(agendaItem.getX() / xspacing)*xspacing+itempadding, (int)agendaItem.getY()+heightoffset);
  77. }
  78. }else if(clickedItem[1] == 2){ //agenda item is resized
  79. if(agendaItem.getHeight() < 30){ //check the height of the item
  80. agendaItem.setSize((int) agendaItem.getWidth(), 30);
  81. }else if(agendaItem.getHeight()+agendaItem.getY() > 48*yspacing+heightoffset){ // outside the window on the bottom
  82. agendaItem.setSize((int)agendaItem.getWidth(),(int) ((48*yspacing+heightoffset)-agendaItem.getY()-1));
  83. }
  84. }
  85. checkCollision(agendaItem);
  86. //update the new data to the Act
  87. agendaItem.setStage(agenda.getStages().get((int) Math.round(agendaItem.getX() / xspacing)), (int) Math.round(agendaItem.getX() / xspacing));
  88. agendaItem.getTime().getBeginTime().set((GregorianCalendar.MINUTE), (int) Math.round((agendaItem.getY()-heightoffset)/45*30)%60);
  89. agendaItem.getTime().getBeginTime().set((GregorianCalendar.HOUR_OF_DAY), (int) Math.round((agendaItem.getY()-heightoffset)/45*30)/60);
  90. agendaItem.getTime().getBeginTime().set(GregorianCalendar.DAY_OF_YEAR, (int) (currentdate.get(Calendar.DAY_OF_YEAR)+(Math.round(agendaItem.getY()-heightoffset)/45*30)/60/24));
  91. agendaItem.getTime().getEndTime().set(GregorianCalendar.MINUTE, (int) Math.round((agendaItem.getY()+agendaItem.getHeight()-heightoffset)/45*30)%60);
  92. agendaItem.getTime().getEndTime().set(GregorianCalendar.HOUR_OF_DAY, (int) Math.round((agendaItem.getY()+agendaItem.getHeight()-heightoffset)/45*30)/60%24);
  93. agendaItem.getTime().getEndTime().set(GregorianCalendar.DAY_OF_YEAR, (int) (currentdate.get(Calendar.DAY_OF_YEAR)+(Math.round(agendaItem.getY()+agendaItem.getHeight()-heightoffset)/45*30)/60/24));
  94. }
  95. }
  96. repaint();
  97. }
  98. }
  99. });
  100. }
  101. public void checkCollision(AgendaItemShape agendaItem){
  102. for(int i = 0; i < agendaItems.size(); i++){ //check if there are any collisions with other items
  103. AgendaItemShape agendaItem2 = agendaItems.get(i);
  104. if(agendaItem2 != agendaItem){
  105. if(agendaItem.intersects(agendaItem2)){ //intersection found
  106. if( agendaItem.getHeight()+agendaItem.getY() > agendaItem2.getY() && agendaItem.getY() > agendaItem2.getY()){//collision on the bottom of another item
  107. agendaItem.setLocation((int)agendaItem.getX(), (int)(agendaItem2.getY()+agendaItem2.getHeight()));
  108. }else if(agendaItem.getY() <= agendaItem2.getY()){//collision on the top of another item
  109. if(clickedItem[1] == 0){//item was moved, only change location
  110. agendaItem.setLocation((int)agendaItem.getX(), (int)(agendaItem2.getY()-agendaItem.getHeight()));
  111. if(agendaItem.getY() < heightoffset){
  112. agendaItem.y = (int) (agendaItem2.getY() + agendaItem2.getHeight());
  113. }
  114. }else if(clickedItem[1] == 2){//item was resized, only change the size
  115. agendaItem.setSize((int)agendaItem.getWidth(), (int)(agendaItem2.getY()-agendaItem.getY()));
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }
  122. public int[] getClickedItem(MouseEvent e){
  123. for(int i = 0; i < agendaItems.size(); i++){
  124. if(agendaItems.get(i).intersects(e.getX(), e.getY()-10, 1, 10)){
  125. if( agendaItems.get(i).getY()+agendaItems.get(i).getHeight()+10 > e.getY() &&
  126. agendaItems.get(i).getY()+agendaItems.get(i).getHeight()-10 < e.getY()){
  127. setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
  128. if(e.getButton() == 1){
  129. return new int[]{i, 2}; //Clicked on the bottom border of the item
  130. }
  131. return new int[]{-1};
  132. }
  133. if(e.getButton() == 1){
  134. setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
  135. return new int[]{i, 0}; // Clicked inside the item
  136. }else{
  137. setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
  138. return new int[]{-1};
  139. }
  140. }
  141. }
  142. setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
  143. return new int[]{-1}; //Clicked outside all the agenda-items so return a -1
  144. }
  145. public void setDate(GregorianCalendar date){
  146. agendaItems.clear();
  147. currentdate = date;
  148. for(Act act : agenda.getActs()){
  149. if(currentdate.compareTo(act.getActTime().getBeginTime()) <= 1 && currentdate.compareTo(act.getActTime().getEndTime()) >= -1){
  150. agendaItems.add(new AgendaItemShape(act, agenda.getStages().indexOf(act.getStage()), new Color(250,209,101)));
  151. }
  152. }
  153. for(AgendaItemShape a:agendaItems){
  154. a.setLocation(0, (int) (((a.getTime().getBeginTime().get(Calendar.DAY_OF_YEAR) - currentdate.get(Calendar.DAY_OF_YEAR))*yspacing*48+heightoffset) + (a.getBeginTime() * (yspacing/30.0))));
  155. a.setSize(0, (int) (a.getLength()* (yspacing/30.0)));
  156. }
  157. repaint();
  158. }
  159. public void paintComponent(Graphics g){
  160. super.paintComponent(g);
  161. Graphics2D g2 = (Graphics2D)g;
  162. if(agenda.getStages().size() == 0){
  163. xspacing = 0;
  164. }else{
  165. xspacing = getWidth()/agenda.getStages().size()+20;
  166. }
  167. for(int i = 0; i <= 48; i++){
  168. if(i%2==0){
  169. g2.setStroke(new BasicStroke(1)); //full at normal hours
  170. g2.setColor(Color.BLACK);
  171. g2.drawString(i/2+":00", 0, i*yspacing+heightoffset);
  172. g2.setColor(new Color (100,100,100, 50));
  173. }else{
  174. g2.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0)); //dashed at half hours
  175. }
  176. g2.drawLine(0, i*yspacing+heightoffset, getWidth(), i*yspacing+heightoffset); //draws the horizontal time lines
  177. }
  178. for(AgendaItemShape agendaItem: agendaItems){
  179. if(clickedItem[0] == -1){ //Window is resized, only resize & place the items
  180. agendaItem.setSize(xspacing-itempadding*2, (int) (agendaItem.getHeight()));
  181. agendaItem.setLocation(agendaItem.getRow()*xspacing+itempadding, (int) agendaItem.getY());
  182. }
  183. g2.setColor(agendaItem.getColor()); //Fills the item with a given color
  184. g2.fill(agendaItem);
  185. if(clickedItem[0] != -1 && agendaItems.get(clickedItem[0]) == agendaItem){
  186. g2.setColor(Color.black);
  187. }else{
  188. g2.setColor(agendaItem.getColor().darker());
  189. }
  190. g2.draw(agendaItem);
  191. g2.setColor(Color.BLACK);
  192. if(agendaItem.getHeight() < 50){
  193. g2.drawString(agendaItem.getName() + " " + agendaItem.getTime().getBeginTimeString() + " - " + agendaItem.getTime().getEndTimeString(), (int)agendaItem.getX() +5, (int)agendaItem.getY() +15);
  194. }else{
  195. g2.drawString(agendaItem.getName(), (int)agendaItem.getX() +5, (int)agendaItem.getY() +15);
  196. g2.drawString(agendaItem.getTime().getBeginTimeString(), (int)agendaItem.getX() +5, (int)agendaItem.getY() +30);
  197. g2.drawString(agendaItem.getTime().getEndTimeString(), (int)agendaItem.getX() +5, (int)agendaItem.getY() +45);
  198. g2.setColor(Color.GRAY);
  199. g2.drawString(".....", (int)(agendaItem.getX() + agendaItem.getWidth()/2), (int)(agendaItem.getY()+agendaItem.getHeight()-10));
  200. }
  201. }
  202. g2.setColor(Color.LIGHT_GRAY);
  203. g2.fillRect(0, 0, getWidth(), heightoffset);
  204. for(int i = 0; i < agenda.getStages().size(); i++){
  205. g2.setColor(Color.black);
  206. g2.drawString(agenda.getStages().get(i).getName(), i*xspacing+itempadding, heightoffset/2);
  207. g2.setColor(new Color (100,100,100, 70));
  208. g2.drawLine(i*xspacing, getHeight(), i*xspacing, 0); //draws the vertical separation lines
  209. }
  210. }
  211. }