728x90

- Ext.Panel의 높이 구하기 : myPanel.container.getHeight()
- dockedItems 첫번째 아이템 타이틀 수정 : this.dockedItems.items[0].setTitle('타이틀수정');
- 오늘날짜구하기 : var currentDate = new Date();
- 문자형날짜값을 날짜형으로 : Date.parseDate(JsonData.data.info.start_date, 'c')
- items 찾기 : writeToolbar.items.get('btnAdd').enable(); / writeToolbar.getChildItemById('btnAdd').disable();
- store record 삭제 : employee_submenu.panel_submenu.getListBox().store.removeAt(2);
- xtype : 'selectfield' option 동적추가 : this.items.get("emp.join").items.get("role").store.add({ text : '슈퍼바이저', value : '01' });

- Ext.data.Store 데이터추가

dataStore = new Ext.data.Store({ // 생략 
dataStore.add({"id": global_user_com_id, "comment": Ext.getCmp("txtComment").getValue()});

- Sencha Ext.XTemplate 데이터 적용시 replace

itemTpl : new Ext.XTemplate(
    '<TPL for=".">',
        '<DIV class=gcomment>',
            '<DIV class=gcomment-title>',
                '<SPAN class=id>{regid}</SPAN><SPAN class=date>{regdate:date("Y년 m월 d일")}</SPAN>',
            '</DIV>', 
            '<DIV class=gcomment-content>',
                '<P>{comment:this.linkify}</P>', 
            '</DIV>', 
        '</DIV>',
    '</TPL>', 
    {
        linkify : function(value) {
            return value.replace(/\n/g, "<br />");
        }
    }
)

- Sencha Ext.XTemplate 데이터 적용시 데이터변환

itemTpl:new Ext.XTemplate(
    '<div class="tweet-bubble">',
        '<div class="tweet-content">',
            '<h1>{title}</h1>',
            '<span>일정 {sdate:this.toDate} ~ {edate:this.toDate}</span>',
        '</div>',
    '</div>',
    '<div class="ttttt">',
        '<p>{insert_date:date("Y년 m월 d일")}</p>',
    '</div>',
    {
        toDate: function(values) {
            return values.substr(0, 4) + '년 ' + values.substr(4, 2) + '월 ' + values.substr(6, 2) + '일';
        }
    }
),              
listeners: {
    selectionchange: function(sel, records) {
        if (records[0] !== undefined) {
            alert(records[0].data.id);
        }
    }
}

Ext.ux.Image

Ext.ux.Image = Ext.extend(Ext.Component, {

    url : Ext.BLANK_IMAGE_URL,  //for initial src value
    
    //cls : 'con_preview',
    
    scale : 1,
    
    style : 'text-align: center;',
    
	html: [
		'<img>'
	],

	initComponent: function() {
		Ext.ux.Image.superclass.initComponent.apply(this, arguments);
		
		this.on('afterrender', this.initViewer, this, {delay: 10, single: true});
		
		this.addEvents('load');
	},
	
	initViewer: function() {
		// retrieve DOM els
		this.imgEl = this.el.down('img');

		this.imgEl.setStyle({
			'-webkit-user-drag': 'none'
			,'-webkit-transform-origin': '0 0'
			,'visibility': 'hidden'
		});

		
		this.el.setStyle({
			//backgroundImage: 'url('+this.previewSrc+')',
			backgroundPosition: 'center center'
			,backgroundRepeat: 'no-repeat'
			,webkitBackgroundSize: 'contain'
		});

		// attach event listeners
		this.mon(this.imgEl, {
			scope: this
			,load: this.onLoad
			//,doubletap: this.onDoubleTap
			//,pinchstart: this.onImagePinchStart
			//,pinch: this.onImagePinch
			//,pinchend: this.onImagePinchEnd
		});


		// load image
		if(this.url) {
			this.setSrc(this.url);	
		}
	},
 

    onLoad: function() {
    	
		this.viewportWidth = this.viewportWidth || this.getWidth() || this.ownerCt.body.getWidth();
		this.viewportHeight = this.viewportHeight || this.getHeight() || this.ownerCt.body.getHeight();
			
		// grab image size
		this.imgWidth = this.imgEl.dom.width
		this.imgHeight = this.imgEl.dom.height;
				
		// calculate and apply initial scale to fit image to screen
		if(this.imgWidth > this.viewportWidth || this.imgHeight > this.viewportHeight)
			this.scale = this.baseScale = Math.min(this.viewportWidth/this.imgWidth, this.viewportHeight/this.imgHeight);
		else
			this.scale = this.baseScale = 1;
		
		// set initial translation to center
		this.translateX = this.translateBaseX = (this.viewportWidth - this.baseScale * this.imgWidth) / 2;
		this.translateY = this.translateBaseY = (this.viewportHeight - this.baseScale * this.imgHeight) / 2;
		
		// show image and remove mask
		this.imgEl.setStyle({ visibility: 'visible' });

		var baseWidth = Math.min(this.viewportWidth, 480);

		this.scale = baseWidth / this.imgWidth;			  					
		
		var boundWidth = this.imgWidth * this.scale;
		var boundHeight = this.imgHeight * this.scale;
		
		this.setHeight(boundHeight);
		
		this.imgEl.setStyle({
			width: boundWidth + 'px'
			,height: boundHeight + 'px'
		});

        this.fireEvent('load', this);
    },
 
    setSrc: function(url) {
    	if(this.imgEl)
			this.imgEl.dom.src = url;
		else
			this.url = url;
			
	},
    
    onStateChange : function(request) {
        if (request && request.xhr && request.xhr.readyState == 4) {
            this.clearTimeout(request);
            this.onComplete(request);
            this.cleanup(request);
        }
    }
});

Dispatching an event on image click in Sencha Touch

	var panel223 = new Ext.Panel({		
		bodyStyle: 'background-image:url(img/mobile_bg.png); background-repeat:repeat',
		scroll: false,
		html : 
			'<table class="duty_view" style="width:100%;padding-top: 9px;">' +
			'<tr><td align="center" style="padding-top: 9px;" colspan="2"><img src="'+common_url+'img/logo.png" width="100%"/></td></tr>' +
			'<tr><td class="txt2" align="center">' +
			'<a style="width:150px" class="large button blue" id="btnApt">APT</a></td><td class="txt2" align="center">'+
			'<a style="width:150px" class="large button blue" id="btnBuilding">Building</a></td></tr>' +			
			'</table>',
			listeners: {
				render: function(c, records){
					c.getEl().on('click', function(event, el){
						alert(el.id);
					}, c, {stopEvent: true});
	 			}
			}
	});


728x90
728x90
TClientDataset 데이터를 XML로 가지고 왔지만,
일본어에 표현에 문제가 발견 되었다.

모든 문자열 데이터의 경우 fieldtype="string"로 사용했는데,
유니코드의 경우 fieldtype="string.uni" 라고
표현해야 TWideStringField로 인식하여 올바르게 데이터가 표현되지만,
영문만 있는경우 또 다시 문제가 발견되었다.

영문만 존재하는 경우 데이터를 모두 확인하여 fieldtype="string"로 했지만,
이것도 임시 방편일뿐 완벽한 처리는 되는 않는다.

TClientDataset 자체의 버그라고 생각되지만, 우선은 이렇게 처리 해두었다.

------------------------------------------------------------------------
FastReport 에도 다국어를 위해서 처리 해야 하는 문제가 발견되었다.
TfrxMemoView 속성에서 UseDefaultCharset 값을 True로 해야 일본어가 올바르게 표시 되었다.

관련 소스 위치

procedure TfrxCustomMemoView.GetData;
var
  i, j: Integer;
  s, s1, s2, dc1, dc2: WideString;
  ThLocale: Cardinal;
  LocCharset: Boolean;
begin
  inherited;
  ThLocale := 0;
  LocCharset := ((Font.Charset <> DEFAULT_CHARSET) and  not FUseDefaultCharset);
  if IsDataField then
  begin
    if DataSet.IsBlobField(DataField) then
    begin
      if LocCharset then
      begin
        ThLocale := GetThreadLocale;
        SetThreadLocale(GetLocalByCharSet(Font.Charset));
      end;
        DataSet.AssignBlobTo(DataField, FMemo);
      if LocCharset then
        SetThreadLocale(ThLocale);
    end
    else
    begin
      FValue := DataSet.Value[DataField];
      if FDisplayFormat.Kind = fkText then
      begin
        if LocCharset then
          FMemo.Text := AnsiToUnicode(AnsiString(DataSet.DisplayText[DataField]), Font.Charset)
     else

       FMemo.Text := DataSet.DisplayText[DataField];

      end
      else FMemo.Text := FormatData(FValue);
      if FHideZeros and (TVarData(FValue).VType <> varString) and
      {$IFDEF Delphi12}(TVarData(FValue).VType <> varUString) and{$ENDIF}
        (TVarData(FValue).VType <> varOleStr) and (FValue = 0) then
        FMemo.Text := '';
    end;
  end
728x90
728x90
출처 : http://dbin318.tistory.com/13

웹페이지 호출 후 오래 걸리는 작업을 실행하는 경우 응답을 바로 할 수 없어서
MQ 시스템을 적용하게 되었습니다.

MQ(Message Queue) 시스템은
Message를 Queue에 전달하고, MQ시스템은 다시 Queue에서 Message을 받아서
Message을 실행하는 것으로, 시스템에서 처리 가능한 용량 만큼만 Queue에 Message을 받아서
처리 하게 됩니다.

부하가 많이 걸리는 SMS 시스템과 같은 시스템에 적용하게 됩니다.

저의 경우는 부하가 많이 걸리는 작업은 아니지만
특정 작업이 1시간 이상 걸리는 작업을 웹페이지에서 호출하는데,
호출후 바로 응답을 받을 수 없는 문제로 MQ 시스템을 적용하게 되었습니다.
(Message을 Queue에 전달하고 바로 응답 페이지를 보여줄 수 있기때문에...비동기식 호출이 가능)

자세한 설명은 출처 페이지에서 보실수 있습니다.

적용환경

Tomcat 7
Spring 3.0.4
ActiveMQ 5.4.3

test-activemq.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans 
  xmlns="http://www.springframework.org/schema/beans" 
  xmlns:amq="http://activemq.apache.org/schema/core"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

	<!-- a pooling based JMS provider -->
	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL">
			<value>vm://localhost</value>
		</property>
	</bean>

	<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
		destroy-method="stop">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>

	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="dbin.queue" />
	</bean>

	<bean id="msgConverter" class="test.dbin.MsgConverterImpl" />
	<bean id="msgMdp" class="test.dbin.MsgMDP" />

	<bean id="purePojoMdp"
		class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
		<property name="delegate" ref="msgMdp" />
		<property name="defaultListenerMethod" value="handleMessage" />
		<property name="messageConverter" ref="msgConverter" />
	</bean>
	
	<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
		<property name="connectionFactory" ref="jmsFactory" />
		<property name="destination" ref="queueDestination" />
		<property name="messageListener" ref="purePojoMdp" />
	</bean>

	<!-- Spring JMS Template -->
	<bean id="producerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="jmsFactory" />
		<property name="defaultDestination" ref="queueDestination" />
		<property name="messageConverter" ref="msgConverter" />
	</bean>

	<bean id="producer" class="test.dbin.MsgProducerImpl">
		<property name="jmsTemplate" ref="producerJmsTemplate" />
	</bean>
</beans>

Msg.java
package test.dbin;

public class Msg {

	private String name;
	private String value;

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public String toString() {
		return "name = " + name + ", value = " + value;
	}

}

MsgProducer.java
package test.dbin;

import org.springframework.jms.core.JmsTemplate;

public interface MsgProducer {
 
	public void send(final Msg map);
 
	public void setJmsTemplate(JmsTemplate jmsTemplate);
 
}

MsgProducerImpl.java
package test.dbin;

import org.springframework.jms.core.JmsTemplate;

public class MsgProducerImpl implements MsgProducer {

	private JmsTemplate jmsTemplate;
 
	public void setJmsTemplate(JmsTemplate jmsTemplate) {
 		this.jmsTemplate = jmsTemplate;
 	}
	
	public void send(final Msg msg) {		
 		jmsTemplate.convertAndSend(msg);
 	}	
 
}

MsgMDP.java
package test.dbin;

/**
 * Message Driven POJO
 *
 */
public class MsgMDP {
 
	public void handleMessage(Msg msg) {
		// handles the message
		System.out.println("handler called");
		System.out.println(msg);
	}
 
}

MsgConverterImpl.java
package test.dbin;
 
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;

/**
 * MapMessage로의 conversion을 담당하는 class
 * 
 *
 */
public class MsgConverterImpl implements MessageConverter {

	public MsgConverterImpl() {

	}

	public Object fromMessage(Message message) throws JMSException, MessageConversionException {
		if( !(message instanceof MapMessage)) {
			throw new MessageConversionException("not MapMessage");
		}
		
		System.out.println("MsgConverterImpl.fromMessage");
		
		MapMessage mapMessage = (MapMessage)message;
		Msg msg = new Msg();
		msg.setName(mapMessage.getString("name"));
		msg.setValue(mapMessage.getString("value"));

		return msg;
	}

	public Message toMessage(Object object, Session session)  throws JMSException, MessageConversionException {
		if ( !(object instanceof Msg) ) {
			throw new MessageConversionException("not Msg");
		}
		
		System.out.println("MsgConverterImpl.toMessage");
		
		Msg msg = (Msg)object;
		MapMessage mapMessage = session.createMapMessage();

		mapMessage.setString("name", msg.getName());
		mapMessage.setString("value", msg.getValue());
		
		return mapMessage;
	}
}

MQController.java
  @Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		Msg msg = new Msg();
		msg.setName("daniel yoon");
		msg.setValue("lullaby");
 		
		// 전송 
		MsgProducer producer = (MsgProducer)BeanUtils.getBean("producer");
		producer.send(msg);
		System.out.println(msg + " sent");
		
		
		ModelAndView mv = new ModelAndView();
		mv.setViewName("/index");

		return mv;
	}
실행결과

MsgConverterImpl.toMessage
MsgConverterImpl.fromMessage
handler called
name = daniel yoon, value = lullaby
name = daniel yoon, value = lullaby sent
728x90
728x90

Path 추가

C:\server\php-5.2.17-Win32-VC6-x86
C:\server\php-5.2.17-Win32-VC6-x86\ext

C:\server\Apache2.2\conf\httpd.conf 수정


# For PHP 5 do something like this:
LoadModule php5_module "C:/server/php-5.2.17-Win32-VC6-x86/php5apache2_2.dll"

Alias /mysql "C:/server/phpMyAdmin-3.4.6-all-languages"

-- 생략 --
 
<Directory "C:/server/phpMyAdmin-3.4.6-all-languages">
 Options FollowSymLinks
 DirectoryIndex index.html index.htm index.php *.jsp *.php
 Order allow,deny
 Allow from all
</Directory>

-- 생략 --

    AddType application/x-httpd-php .php .php3 .html .htm .phtml
    AddType application/x-httpd-php-source .phps

php.ini 파일 생성

php.ini-recommended 파일 C:\server\Apache2.2\bin 폴더에 복사

C:\server\Apache2.2\bin\php.ini 수정 (주석제거)

extension=php_bz2.dll
extension=php_mcrypt.dll
extension=php_mysql.dll
extension=php_mysqli.dll
extension=php_openssl.dll
extension=php_pdo_mysql.dll
extension=php_zip.dll

config.inc.php 생성

C:\server\phpMyAdmin-3.4.6-all-languages\config.sample.inc.php 파일 config.inc.php 로 이름 변경

config.inc.php 수정

<?php
/*
 * Generated configuration file
 * Generated by: phpMyAdmin 3.4.6 setup script
 * Date: Tue, 18 Oct 2011 17:43:55 +0900
 */

/* Servers configuration */
$i = 0;

/* Server: cmxdb [1] */
$i++;
$cfg['Servers'][$i]['verbose'] = 'mysql';
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['port'] = 3306;
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['user'] = '';
$cfg['Servers'][$i]['password'] = '';

/* End of servers configuration */

$cfg['blowfish_secret'] = '';
$cfg['DefaultLang'] = 'en';
$cfg['ServerDefault'] = 1;
$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';
?>

728x90
728x90

출처

서비스 등록

httpd -k install -n "Apache2.2" -f "C:\server\Apache2.2\conf\httpd.conf"

서비스 제거

httpd -k uninstall -n "Apache2.2"

환경파일(httpd.conf) syntax 확인

C:\server\Apache2.2\bin>httpd -n "Apache2.2" -t
httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.123.104 for ServerName
Syntax OK

서비스 실행

httpd -n "Apache2.2" -k start
또는
net start "Apache2.2"

서비스 종료

httpd -n "Apache2.2" -k shutdown
또는
net stop "Apache2.2"
728x90
728x90
행추가
ws.InsertRows(row+1, 1);

행삭제
ws.DeleteRows(row, row+4);

셀병합
ws.MergeCells(1, p_row, 1, row-1);

테두리     
ws.Range.ItemsRef['A'+inttostr(2)+':'+'A'+inttostr(row)].BorderOutlineStyle := cbsThin; // cbsHair;

가운데 설정
ws.Cell[9, row].HorizAlignment := chaCenter;

몇 가지 설정
ws.Cell[i, row].NumberFormat := '_-* #,##0_-;-* #,##0_-;_-* ""-""_-;_-@_-';
ws.Cell[9, row].NumberFormat := '0%';

셀높이 설정
ws.Rows[(i*28)+2].Height := ws.Rows[2].Height;

셀복사
XLS01.CopyCells(SheetIndex, 0,0,7,27, SheetIndex, 0,(i*28));

출력 설정
XLS01.Sheet[SheetIndex].PrintSettings.Options := [psoHorizCenter];
XLS01.Sheet[SheetIndex].PrintSettings.HorizPagebreaks.Clear;
//
HorizPagebreak := ws.PrintSettings.HorizPagebreaks.Add;
HorizPagebreak.Row := (loopRow*28)+addRow-tmpAddRow-1;

배경색 지정

function RGBToColor(R,G,B:Byte): TColor;
begin
Result:=B Shl 16 Or
G Shl 8 Or
R;
end;

color := RGBToColor(255,255,0)
ws.Range.ItemsRef['A'+IntToStr(row)+':'+GetRowStr(col)+IntToStr(row)].FillPatternForeColor := TColorToClosestXColor(color);
728x90
728x90
출처 : http://elkha-textcube.blogspot.com/2009/11/phpmyadmin-%EC%84%A4%EC%B9%98.html

1. 다운로드 (http://www.phpmyadmin.net/home_page/index.php)

2. 압축풀기

phpMyAdmin-3.4.6-all-languages.7z 압축파일를
C:\server\phpMyAdmin-3.4.6-all-languages 폴더에 풀어 둔다.

3. config.inc.php 파일 생성

C:\server\phpMyAdmin-3.4.6-all-languages\libraries\config.default.php 파일를
config.inc.php 복사한다.

4. 환경파일 수정(config.inc.php)

$cfg['PmaAbsoluteUri'] = 'http://localhost/mysql';
$cfg['blowfish_secret'] = 'cookie'; // cookie 값 입력 (아무거나 입력해도 됨)
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['port'] = '3306';
$cfg['Servers'][$i]['auth_type'] = 'cookie'; (작동 안되면 http 입력)
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'mysql 비밀번호';

5. httpd.conf 가상폴더 추가

Alias /mysql "C:/server/phpMyAdmin-3.4.6-all-languages"
 
<Directory "C:/server/phpMyAdmin-3.4.6-all-languages">
 Options FollowSymLinks
 DirectoryIndex index.html index.htm index.php *.jsp *.php
 Order allow,deny
 Allow from all
</Directory>

6. C:\Windows\php.ini 수정

주석 ; 제거

;extension=php_mysql.dll
;extension=php_mysqli.dll


728x90
728x90
출처 : http://www.ibm.com/developerworks/kr/library/j-jstl0520/

JAR 파일 추가 

jstl-1.2.jar 파일를 WEB-INF/lib 밑에 복사합니다.

WEB-INF/web.xml 편집 불필요

jstl-1.2.jar에 내장되어 있어 web.xml 편집 필요 없음

JSP 파일 작성

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>JSTL SQL Test</title>
</head>
<body>

<sql:setDataSource dataSource="jdbc/testDS"/> 
<sql:query var="items" sql="SELECT * FROM user_info">
</sql:query>

<table border="1" align="center" valign="center">
<c:forEach var="row" items="${items.rows}">
<tr>
<td><c:out value="${row.user_id}"/></td>
</tr>
</c:forEach>
</table>

</body>
</html>

728x90

+ Recent posts